chore: cleanup proof
This commit is contained in:
parent
2a37f53fca
commit
5ca9b49235
1 changed files with 17 additions and 15 deletions
|
|
@ -74,8 +74,12 @@ def Expr.typeCheck (e : Expr) : {{ ty | HasType e ty }} :=
|
|||
| .found .bool h₁, .found .bool h₂ => .found .bool (.and h₁ h₂)
|
||||
| _, _ => .unknown
|
||||
|
||||
theorem Expr.typeCheck_correct (h₁ : HasType e ty) (h₂ : e.typeCheck ≠ .unknown) : e.typeCheck = .found ty h := by
|
||||
revert h₂
|
||||
cases typeCheck e with
|
||||
| found ty' h' => intro; have := HasType.det h₁ h'; subst this; rfl
|
||||
| unknown => intros; contradiction
|
||||
|
||||
-- TODO: for simplifying the following proof we need: ematching for forward reasoning, and `match` blast for case analysis
|
||||
/-|
|
||||
Now, we prove that if `Expr.typeCheck e` returns `Maybe.unknown`, then forall `ty`, `HasType e ty` does not hold.
|
||||
The notation `e.typeCheck` is sugar for `Expr.typeCheck e`. Lean can infer this because we explicitly said that `e` has type `Expr`.
|
||||
|
|
@ -87,21 +91,19 @@ the cases corresponding to the constructors `Expr.nat` and `Expr.bool`.
|
|||
theorem Expr.typeCheck_complete {e : Expr} : e.typeCheck = .unknown → ¬ HasType e ty := by
|
||||
induction e with simp [typeCheck]
|
||||
| plus a b iha ihb =>
|
||||
revert iha ihb
|
||||
cases typeCheck a <;> cases typeCheck b <;> simp <;> intros <;> intro h <;> cases h <;> try contradiction
|
||||
rename_i ty₁ _ ty₂ _ h _ _
|
||||
cases ty₁ <;> cases ty₂ <;> simp at h
|
||||
· have := HasType.det ‹HasType b Ty.bool› ‹HasType b Ty.nat›; contradiction
|
||||
· have := HasType.det ‹HasType a Ty.bool› ‹HasType a Ty.nat›; contradiction
|
||||
· have := HasType.det ‹HasType a Ty.bool› ‹HasType a Ty.nat›; contradiction
|
||||
split
|
||||
next => intros; contradiction
|
||||
next ra rb hnp => -- Recall that hnp is a hypothesis generated by the `split` tactic that asserts the previous case was not taken
|
||||
intro h ht
|
||||
cases ht with
|
||||
| plus h₁ h₂ => exact hnp h₁ h₂ (typeCheck_correct h₁ (iha · h₁)) (typeCheck_correct h₂ (ihb · h₂))
|
||||
| and a b iha ihb =>
|
||||
revert iha ihb
|
||||
cases typeCheck a <;> cases typeCheck b <;> simp <;> intros <;> intro h <;> cases h <;> try contradiction
|
||||
rename_i ty₁ _ ty₂ _ h _ _
|
||||
cases ty₁ <;> cases ty₂ <;> simp at h
|
||||
· have := HasType.det ‹HasType b Ty.bool› ‹HasType b Ty.nat›; contradiction
|
||||
· have := HasType.det ‹HasType a Ty.bool› ‹HasType a Ty.nat›; contradiction
|
||||
· have := HasType.det ‹HasType b Ty.bool› ‹HasType b Ty.nat›; contradiction
|
||||
split
|
||||
next => intros; contradiction
|
||||
next ra rb hnp =>
|
||||
intro h ht
|
||||
cases ht with
|
||||
| and h₁ h₂ => exact hnp h₁ h₂ (typeCheck_correct h₁ (iha · h₁)) (typeCheck_correct h₂ (ihb · h₂))
|
||||
|
||||
/-|
|
||||
Finally, we show that type checking for `e` can be decided using `Expr.typeCheck`.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue