lean4-htt/tests/lean/run/assoc_flat.lean

66 lines
2.3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

open tactic expr
constant nat.add_assoc (a b c : nat) : (a + b) + c = a + (b + c)
meta definition is_op_app (op : expr) (e : expr) : option (expr × expr) :=
match e with
| (app (app fn a1) a2) := if op = fn then some (a1, a2) else none
| e := none
end
meta definition flat_with : expr → expr → expr → expr → tactic (expr × expr)
| op assoc e rhs :=
match (is_op_app op e) with
| (some (a1, a2)) := do
-- H₁ is a proof for a2 + rhs = rhs₁
(rhs₁, H₁) ← flat_with op assoc a2 rhs,
-- H₂ is a proof for a1 + rhs₁ = rhs₂
(new_app, H₂) ← flat_with op assoc a1 rhs₁,
-- We need to generate a proof that (a1 + a2) + rhs = a1 + (a2 + rhs)
-- H₃ is a proof for (a1 + a2) + rhs = a1 + (a2 + rhs)
H₃ : expr ← return (app (app (app assoc a1) a2) rhs),
-- H₃ is a proof for a1 + (a2 + rhs) = a1 + rhs1
H₄ : expr ← mk_app `congr_arg [app op a1, H₁],
H₅ ← mk_app `eq.trans [H₃, H₄],
H ← mk_app `eq.trans [H₅, H₂],
return (new_app, H)
| none := do
new_app ← return $ app (app op e) rhs,
H ← mk_app `eq.refl [new_app],
return (new_app, H)
end
meta definition flat : expr → expr → expr → tactic (expr × expr)
| op assoc e :=
match (is_op_app op e) with
| (some (a1, a2)) := do
-- H₁ is a proof that a2 = new_a2
(new_a2, H₁) ← flat op assoc a2,
-- H₂ is a proof that a1 + new_a2 = new_app
(new_app, H₂) ← flat_with op assoc a1 new_a2,
-- We need a proof that (a1 + a2) = new_app
-- H₃ is a proof for a1 + a2 = a1 + new_a2
H₃ : expr ← mk_app `congr_arg [app op a1, H₁],
H ← mk_app `eq.trans [H₃, H₂],
return (new_app, H)
| none :=
do pr ← mk_app `eq.refl [e],
return (e, pr)
end
local infix `+` := nat.add
set_option trace.app_builder true
set_option pp.all true
example (a b c d e f g : nat) : ((a + b) + c) + ((d + e) + (f + g)) = a + (b + (c + (d + (e + (f + g))))) :=
by do
assoc : expr ← mk_const $ `nat.add_assoc,
op : expr ← mk_const $ `nat.add,
tgt ← target,
match (is_eq tgt) with
| (some (lhs, rhs)) := do
r ← flat op assoc lhs,
trace (prod.snd r),
exact (prod.snd r)
| none := failed
end