universe variables u namespace foo variables {α : Type u} open smt_tactic meta def no_ac : smt_config := { cc_cfg := { ac := ff }} meta def blast : tactic unit := using_smt_with no_ac $ intros >> repeat (ematch >> try close) section add_comm_monoid variables [add_comm_monoid α] attribute [ematch] add_comm add_assoc theorem add_comm_three (a b c : α) : a + b + c = c + b + a := by blast theorem add.comm4 : ∀ (n m k l : α), n + m + (k + l) = n + k + (m + l) := by blast end add_comm_monoid section group variable [group α] attribute [ematch] mul_assoc mul_left_inv one_mul theorem inv_mul_cancel_left (a b : α) : a⁻¹ * (a * b) = b := by blast end group namespace subt constant subt : nat → nat → Prop axiom subt_trans {a b c : nat} : subt a b → subt b c → subt a c attribute [ematch] subt_trans lemma ex (a b c d : nat) : subt a b → subt b c → subt c d → subt a d := by blast end subt section ring variables [ring α] (a b : α) attribute [ematch] zero_mul lemma ex2 : a = 0 → a * b = 0 := by blast definition ex1 (a b : int) : a = 0 → a * b = 0 := by blast end ring namespace cast1 constant C : nat → Type constant f : ∀ n, C n → C n axiom fax (n : nat) (a : C (2*n)) : (: f (2*n) a :) = a attribute [ematch] fax lemma ex3 (n m : nat) (a : C n) : n = 2*m → f n a = a := by blast end cast1 namespace cast2 constant C : nat → Type constant f : ∀ n, C n → C n constant g : ∀ n, C n → C n → C n axiom gffax (n : nat) (a b : C n) : (: g n (f n a) (f n b) :) = a attribute [ematch] gffax lemma ex4 (n m : nat) (a c : C n) (b : C m) : n = m → a == f m b → g n a (f n c) == b := by blast end cast2 namespace cast3 constant C : nat → Type constant f : ∀ n, C n → C n constant g : ∀ n, C n → C n → C n axiom gffax (n : nat) (a b : C n) : (: g n a b :) = a attribute [ematch] gffax lemma ex5 (n m : nat) (a c : C n) (b : C m) (e : m = n) : a == b → g n a a == b := by blast end cast3 namespace tuple constant {α} tuple: Type α → nat → Type α constant nil {α : Type u} : tuple α 0 constant append {α : Type u} {n m : nat} : tuple α n → tuple α m → tuple α (n + m) infix ` ++ ` := append axiom append_assoc {α : Type u} {n₁ n₂ n₃ : nat} (v₁ : tuple α n₁) (v₂ : tuple α n₂) (v₃ : tuple α n₃) : (v₁ ++ v₂) ++ v₃ == v₁ ++ (v₂ ++ v₃) attribute [ematch] append_assoc variables {p m n q : nat} variables {xs : tuple α m} variables {ys : tuple α n} variables {zs : tuple α p} variables {ws : tuple α q} lemma ex6 : p = m + n → zs == xs ++ ys → zs ++ ws == xs ++ (ys ++ ws) := by blast def ex : p = n + m → zs == xs ++ ys → zs ++ ws == xs ++ (ys ++ ws) := by blast end tuple end foo