Built with Alectryon. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+โ†‘ Ctrl+โ†“ to navigate, Ctrl+๐Ÿ–ฑ๏ธ to focus. On Mac, use โŒ˜ instead of Ctrl.
Hover-Settings: Show types: Show goals:
/-
Inspired by https://leanprover.zulipchat.com/#narrow/stream/236449-Program-verification/topic/.E2.9C.94.20Small-step.20operational.20semantics
-/
import Batteries.Tactic.Basic
-- import Batteries.Tactic.RCases
import Batteries.CodeAction

inductive Tm where
| C : Nat โ†’ Tm
| P : Tm โ†’ Tm โ†’ Tm

namespace Tm

def evalF: Tm โ†’ Nat
| C n => n
| P l r => l.evalF + r.evalF

set_option hygiene false in
infixl:25 " ==> " => eval

inductive eval : Tm โ†’ Nat โ†’ Prop where
| EConst : โˆ€ n, C n ==> n
| EPlus : โˆ€ tโ‚ tโ‚‚ nโ‚ nโ‚‚,
    tโ‚ ==> nโ‚ โ†’
    tโ‚‚ ==> nโ‚‚ โ†’
    P tโ‚ tโ‚‚ ==> nโ‚ + nโ‚‚

-- Repeating this helps delaboration
infixl:25 " ==> " => eval

set_option hygiene false in
infixl:25 " ~~> " => step

inductive step : Tm โ†’ Tm โ†’ Prop where
| StPlusConstConst :
    P (C nโ‚) (C nโ‚‚) ~~> C (nโ‚ + nโ‚‚)
| StPlusLeft (tโ‚ tโ‚' tโ‚‚ : Tm):
    tโ‚ ~~> tโ‚' โ†’
    P tโ‚ tโ‚‚ ~~> P tโ‚' tโ‚‚
| StPlusRight (tโ‚‚ tโ‚‚' : Tm):
    tโ‚‚ ~~> tโ‚‚' โ†’
    P (C n) tโ‚‚ ~~> P (C n) tโ‚‚'

-- Repeating this helps delaboration
infixl:25 " ~~> " => step

end Tm

def Relation (ฮฑ: Type) := ฮฑ โ†’ ฮฑ โ†’ Prop

def Relation.deterministic (R: Relation ฮฑ) : Prop :=
  โˆ€ {x yโ‚ yโ‚‚: ฮฑ}, R x yโ‚ โ†’ R x yโ‚‚ โ†’ yโ‚ = yโ‚‚

theorem EvalSmallStep.deterministic : Relation.deterministic Tm.step := 

Goals accomplished! ๐Ÿ™

โˆ€ {x yโ‚ yโ‚‚ : Tm}, x ~~> yโ‚ โ†’ x ~~> yโ‚‚ โ†’ yโ‚ = yโ‚‚
x, yโ‚, yโ‚‚: Tm
hyโ‚: x ~~> yโ‚
hyโ‚‚: x ~~> yโ‚‚

yโ‚ = yโ‚‚
x, yโ‚: Tm
nโ‚โœ, nโ‚‚โœ: Nat
yโ‚‚: Tm
hyโ‚‚: (Tm.C nโ‚โœ).P (Tm.C nโ‚‚โœ) ~~> yโ‚‚

StPlusConstConst
Tm.C (nโ‚โœ + nโ‚‚โœ) = yโ‚‚
x, yโ‚, tโ‚โœ, tโ‚'โœ, tโ‚‚โœ: Tm
aโœ: tโ‚โœ ~~> tโ‚'โœ
a_ihโœ: โˆ€ {yโ‚‚ : Tm}, tโ‚โœ ~~> yโ‚‚ โ†’ tโ‚'โœ = yโ‚‚
yโ‚‚: Tm
hyโ‚‚: tโ‚โœ.P tโ‚‚โœ ~~> yโ‚‚
tโ‚'โœ.P tโ‚‚โœ = yโ‚‚
x, yโ‚: Tm
nโœ: Nat
tโ‚‚โœ, tโ‚‚'โœ: Tm
aโœ: tโ‚‚โœ ~~> tโ‚‚'โœ
a_ihโœ: โˆ€ {yโ‚‚ : Tm}, tโ‚‚โœ ~~> yโ‚‚ โ†’ tโ‚‚'โœ = yโ‚‚
yโ‚‚: Tm
hyโ‚‚: (Tm.C nโœ).P tโ‚‚โœ ~~> yโ‚‚
(Tm.C nโœ).P tโ‚‚'โœ = yโ‚‚
x, yโ‚: Tm
nโ‚โœ, nโ‚‚โœ: Nat
yโ‚‚: Tm
hyโ‚‚: (Tm.C nโ‚โœ).P (Tm.C nโ‚‚โœ) ~~> yโ‚‚

StPlusConstConst
Tm.C (nโ‚โœ + nโ‚‚โœ) = yโ‚‚
x, yโ‚, tโ‚โœ, tโ‚'โœ, tโ‚‚โœ: Tm
aโœ: tโ‚โœ ~~> tโ‚'โœ
a_ihโœ: โˆ€ {yโ‚‚ : Tm}, tโ‚โœ ~~> yโ‚‚ โ†’ tโ‚'โœ = yโ‚‚
yโ‚‚: Tm
hyโ‚‚: tโ‚โœ.P tโ‚‚โœ ~~> yโ‚‚
tโ‚'โœ.P tโ‚‚โœ = yโ‚‚
x, yโ‚: Tm
nโœ: Nat
tโ‚‚โœ, tโ‚‚'โœ: Tm
aโœ: tโ‚‚โœ ~~> tโ‚‚'โœ
a_ihโœ: โˆ€ {yโ‚‚ : Tm}, tโ‚‚โœ ~~> yโ‚‚ โ†’ tโ‚‚'โœ = yโ‚‚
yโ‚‚: Tm
hyโ‚‚: (Tm.C nโœ).P tโ‚‚โœ ~~> yโ‚‚
(Tm.C nโœ).P tโ‚‚'โœ = yโ‚‚
x, yโ‚: Tm
nโ‚โœ, nโ‚‚โœ: Nat
yโ‚‚: Tm
hyโ‚‚: (Tm.C nโ‚โœ).P (Tm.C nโ‚‚โœ) ~~> yโ‚‚

StPlusConstConst
Tm.C (nโ‚โœ + nโ‚‚โœ) = yโ‚‚
x, yโ‚: Tm
nโœ: Nat
tโ‚‚'โœ: Tm
nโ‚‚โœ: Nat
aโœ: Tm.C nโ‚‚โœ ~~> tโ‚‚'โœ
a_ihโœ: โˆ€ {yโ‚‚ : Tm}, Tm.C nโ‚‚โœ ~~> yโ‚‚ โ†’ tโ‚‚'โœ = yโ‚‚

StPlusRight.StPlusConstConst
(Tm.C nโœ).P tโ‚‚'โœ = Tm.C (nโœ + nโ‚‚โœ)
x, yโ‚: Tm
nโœ: Nat
tโ‚‚โœ, tโ‚‚'โœ: Tm
aโœยน: tโ‚‚โœ ~~> tโ‚‚'โœ
a_ihโœ: โˆ€ {yโ‚‚ : Tm}, tโ‚‚โœ ~~> yโ‚‚ โ†’ tโ‚‚'โœ = yโ‚‚
tโ‚'โœ: Tm
aโœ: Tm.C nโœ ~~> tโ‚'โœ
(Tm.C nโœ).P tโ‚‚'โœ = tโ‚'โœ.P tโ‚‚โœ
x, yโ‚: Tm
nโœ: Nat
tโ‚‚โœ, tโ‚‚'โœยน: Tm
aโœยน: tโ‚‚โœ ~~> tโ‚‚'โœยน
a_ihโœ: โˆ€ {yโ‚‚ : Tm}, tโ‚‚โœ ~~> yโ‚‚ โ†’ tโ‚‚'โœยน = yโ‚‚
tโ‚‚'โœ: Tm
aโœ: tโ‚‚โœ ~~> tโ‚‚'โœ
(Tm.C nโœ).P tโ‚‚'โœยน = (Tm.C nโœ).P tโ‚‚'โœ
x, yโ‚, tโ‚'โœ: Tm
nโ‚โœ, nโ‚‚โœ: Nat
aโœ: Tm.C nโ‚โœ ~~> tโ‚'โœ
a_ihโœ: โˆ€ {yโ‚‚ : Tm}, Tm.C nโ‚โœ ~~> yโ‚‚ โ†’ tโ‚'โœ = yโ‚‚

StPlusLeft.StPlusConstConst
tโ‚'โœ.P (Tm.C nโ‚‚โœ) = Tm.C (nโ‚โœ + nโ‚‚โœ)
x, yโ‚, tโ‚โœ, tโ‚'โœยน, tโ‚‚โœ: Tm
aโœยน: tโ‚โœ ~~> tโ‚'โœยน
a_ihโœ: โˆ€ {yโ‚‚ : Tm}, tโ‚โœ ~~> yโ‚‚ โ†’ tโ‚'โœยน = yโ‚‚
tโ‚'โœ: Tm
aโœ: tโ‚โœ ~~> tโ‚'โœ
tโ‚'โœยน.P tโ‚‚โœ = tโ‚'โœ.P tโ‚‚โœ
x, yโ‚, tโ‚'โœ, tโ‚‚โœ: Tm
nโœ: Nat
tโ‚‚'โœ: Tm
aโœยน: Tm.C nโœ ~~> tโ‚'โœ
a_ihโœ: โˆ€ {yโ‚‚ : Tm}, Tm.C nโœ ~~> yโ‚‚ โ†’ tโ‚'โœ = yโ‚‚
aโœ: tโ‚‚โœ ~~> tโ‚‚'โœ
tโ‚'โœ.P tโ‚‚โœ = (Tm.C nโœ).P tโ‚‚'โœ
x, yโ‚: Tm
nโœ: Nat
tโ‚‚โœ, tโ‚‚'โœ: Tm
aโœ: tโ‚‚โœ ~~> tโ‚‚'โœ
a_ihโœ: โˆ€ {yโ‚‚ : Tm}, tโ‚‚โœ ~~> yโ‚‚ โ†’ tโ‚‚'โœ = yโ‚‚
tโ‚'โœ: Tm
h: Tm.C nโœ ~~> tโ‚'โœ

StPlusRight.StPlusLeft
(Tm.C nโœ).P tโ‚‚'โœ = tโ‚'โœ.P tโ‚‚โœ
x, yโ‚: Tm
nโ‚โœ, h: Nat

StPlusConstConst.StPlusConstConst
Tm.C (nโ‚โœ + h) = Tm.C (nโ‚โœ + h)
x, yโ‚: Tm
nโ‚โœ, nโ‚‚โœ: Nat
tโ‚'โœ: Tm
h: Tm.C nโ‚โœ ~~> tโ‚'โœ
Tm.C (nโ‚โœ + nโ‚‚โœ) = tโ‚'โœ.P (Tm.C nโ‚‚โœ)
x, yโ‚: Tm
nโ‚โœ, nโ‚‚โœ: Nat
tโ‚‚'โœ: Tm
h: Tm.C nโ‚‚โœ ~~> tโ‚‚'โœ
Tm.C (nโ‚โœ + nโ‚‚โœ) = (Tm.C nโ‚โœ).P tโ‚‚'โœ
x, yโ‚: Tm
nโ‚โœ, nโ‚‚โœ: Nat
tโ‚‚'โœ: Tm
h: Tm.C nโ‚‚โœ ~~> tโ‚‚'โœ

StPlusConstConst.StPlusRight
Tm.C (nโ‚โœ + nโ‚‚โœ) = (Tm.C nโ‚โœ).P tโ‚‚'โœ
x, yโ‚: Tm
nโ‚โœ, nโ‚‚โœ: Nat
tโ‚'โœ: Tm
h: Tm.C nโ‚โœ ~~> tโ‚'โœ

StPlusConstConst.StPlusLeft
Tm.C (nโ‚โœ + nโ‚‚โœ) = tโ‚'โœ.P (Tm.C nโ‚‚โœ)
x, yโ‚: Tm
nโ‚โœ, nโ‚‚โœ: Nat
tโ‚‚'โœ: Tm
h: Tm.C nโ‚‚โœ ~~> tโ‚‚'โœ

StPlusConstConst.StPlusRight
Tm.C (nโ‚โœ + nโ‚‚โœ) = (Tm.C nโ‚โœ).P tโ‚‚'โœ
x, yโ‚: Tm
nโœ: Nat
tโ‚‚'โœ: Tm
nโ‚‚โœ: Nat
aโœ: Tm.C nโ‚‚โœ ~~> tโ‚‚'โœ
h: โˆ€ {yโ‚‚ : Tm}, Tm.C nโ‚‚โœ ~~> yโ‚‚ โ†’ tโ‚‚'โœ = yโ‚‚
xโœ: Tm.C nโ‚‚โœ ~~> ?m.7903 โ†’ tโ‚‚'โœ = ?m.7903

StPlusRight.StPlusConstConst
(Tm.C nโœ).P tโ‚‚'โœ = Tm.C (nโœ + nโ‚‚โœ)
x, yโ‚: Tm
nโ‚โœ, nโ‚‚โœ: Nat
yโ‚‚: Tm
hyโ‚‚: (Tm.C nโ‚โœ).P (Tm.C nโ‚‚โœ) ~~> yโ‚‚

StPlusConstConst
Tm.C (nโ‚โœ + nโ‚‚โœ) = yโ‚‚
x, yโ‚: Tm
nโœ: Nat
tโ‚‚โœ, tโ‚‚'โœ: Tm
h: tโ‚‚โœ ~~> tโ‚‚'โœ
hP: โˆ€ {yโ‚‚ : Tm}, tโ‚‚โœ ~~> yโ‚‚ โ†’ tโ‚‚'โœ = yโ‚‚
yโ‚‚: Tm
hyโ‚‚: (Tm.C nโœ).P tโ‚‚โœ ~~> yโ‚‚

StPlusRight
(Tm.C nโœ).P tโ‚‚'โœ = yโ‚‚
;
x, yโ‚, tโ‚'โœ: Tm
nโ‚โœ, nโ‚‚โœ: Nat
h: Tm.C nโ‚โœ ~~> tโ‚'โœ
hP: โˆ€ {yโ‚‚ : Tm}, Tm.C nโ‚โœ ~~> yโ‚‚ โ†’ tโ‚'โœ = yโ‚‚

StPlusLeft.StPlusConstConst
tโ‚'โœ.P (Tm.C nโ‚‚โœ) = Tm.C (nโ‚โœ + nโ‚‚โœ)
x, yโ‚, tโ‚โœ, tโ‚'โœยน, tโ‚‚โœ: Tm
h: tโ‚โœ ~~> tโ‚'โœยน
hP: โˆ€ {yโ‚‚ : Tm}, tโ‚โœ ~~> yโ‚‚ โ†’ tโ‚'โœยน = yโ‚‚
tโ‚'โœ: Tm
aโœ: tโ‚โœ ~~> tโ‚'โœ
tโ‚'โœยน.P tโ‚‚โœ = tโ‚'โœ.P tโ‚‚โœ
x, yโ‚, tโ‚'โœ, tโ‚‚โœ: Tm
nโœ: Nat
tโ‚‚'โœ: Tm
h: Tm.C nโœ ~~> tโ‚'โœ
hP: โˆ€ {yโ‚‚ : Tm}, Tm.C nโœ ~~> yโ‚‚ โ†’ tโ‚'โœ = yโ‚‚
aโœ: tโ‚‚โœ ~~> tโ‚‚'โœ
tโ‚'โœ.P tโ‚‚โœ = (Tm.C nโœ).P tโ‚‚'โœ
x, yโ‚, tโ‚'โœ: Tm
nโ‚โœ, nโ‚‚โœ: Nat
h: Tm.C nโ‚โœ ~~> tโ‚'โœ
hP: โˆ€ {yโ‚‚ : Tm}, Tm.C nโ‚โœ ~~> yโ‚‚ โ†’ tโ‚'โœ = yโ‚‚

StPlusLeft.StPlusConstConst
tโ‚'โœ.P (Tm.C nโ‚‚โœ) = Tm.C (nโ‚โœ + nโ‚‚โœ)
x, yโ‚, tโ‚โœ, tโ‚'โœยน, tโ‚‚โœ: Tm
h: tโ‚โœ ~~> tโ‚'โœยน
hP: โˆ€ {yโ‚‚ : Tm}, tโ‚โœ ~~> yโ‚‚ โ†’ tโ‚'โœยน = yโ‚‚
tโ‚'โœ: Tm
aโœ: tโ‚โœ ~~> tโ‚'โœ
tโ‚'โœยน.P tโ‚‚โœ = tโ‚'โœ.P tโ‚‚โœ
x, yโ‚, tโ‚'โœ, tโ‚‚โœ: Tm
nโœ: Nat
tโ‚‚'โœ: Tm
h: Tm.C nโœ ~~> tโ‚'โœ
hP: โˆ€ {yโ‚‚ : Tm}, Tm.C nโœ ~~> yโ‚‚ โ†’ tโ‚'โœ = yโ‚‚
aโœ: tโ‚‚โœ ~~> tโ‚‚'โœ
tโ‚'โœ.P tโ‚‚โœ = (Tm.C nโœ).P tโ‚‚'โœ
x, yโ‚, tโ‚'โœ: Tm
nโ‚โœ, nโ‚‚โœ: Nat
h: Tm.C nโ‚โœ ~~> tโ‚'โœ
hP: โˆ€ {yโ‚‚ : Tm}, Tm.C nโ‚โœ ~~> yโ‚‚ โ†’ tโ‚'โœ = yโ‚‚

StPlusLeft.StPlusConstConst
tโ‚'โœ.P (Tm.C nโ‚‚โœ) = Tm.C (nโ‚โœ + nโ‚‚โœ)

Goals accomplished! ๐Ÿ™
x, yโ‚, tโ‚'โœ: Tm
nโ‚โœ, nโ‚‚โœ: Nat
h: Tm.C nโ‚โœ ~~> tโ‚'โœ
hP: โˆ€ {yโ‚‚ : Tm}, Tm.C nโ‚โœ ~~> yโ‚‚ โ†’ tโ‚'โœ = yโ‚‚

StPlusLeft.StPlusConstConst
tโ‚'โœ.P (Tm.C nโ‚‚โœ) = Tm.C (nโ‚โœ + nโ‚‚โœ)
x, yโ‚, tโ‚โœ, tโ‚'โœยน, tโ‚‚โœ: Tm
h: tโ‚โœ ~~> tโ‚'โœยน
hP: โˆ€ {yโ‚‚ : Tm}, tโ‚โœ ~~> yโ‚‚ โ†’ tโ‚'โœยน = yโ‚‚
tโ‚'โœ: Tm
aโœ: tโ‚โœ ~~> tโ‚'โœ
xโœ: ?m.7491

StPlusLeft.StPlusLeft
tโ‚'โœยน.P tโ‚‚โœ = tโ‚'โœ.P tโ‚‚โœ
x, yโ‚, tโ‚'โœ: Tm
nโ‚โœ, nโ‚‚โœ: Nat
h: Tm.C nโ‚โœ ~~> tโ‚'โœ
hP: โˆ€ {yโ‚‚ : Tm}, Tm.C nโ‚โœ ~~> yโ‚‚ โ†’ tโ‚'โœ = yโ‚‚

StPlusLeft.StPlusConstConst
tโ‚'โœ.P (Tm.C nโ‚‚โœ) = Tm.C (nโ‚โœ + nโ‚‚โœ)
x, yโ‚, tโ‚โœ, tโ‚'โœยน, tโ‚‚โœ: Tm
h: tโ‚โœ ~~> tโ‚'โœยน
hP: โˆ€ {yโ‚‚ : Tm}, tโ‚โœ ~~> yโ‚‚ โ†’ tโ‚'โœยน = yโ‚‚
tโ‚'โœ: Tm
aโœ: tโ‚โœ ~~> tโ‚'โœ

StPlusLeft.StPlusLeft
tโ‚'โœยน.P tโ‚‚โœ = tโ‚'โœ.P tโ‚‚โœ
x, yโ‚, tโ‚โœ, tโ‚'โœยน, tโ‚‚โœ: Tm
h: tโ‚โœ ~~> tโ‚'โœยน
hP: โˆ€ {yโ‚‚ : Tm}, tโ‚โœ ~~> yโ‚‚ โ†’ tโ‚'โœยน = yโ‚‚
tโ‚'โœ: Tm
h': tโ‚โœ ~~> tโ‚'โœ

StPlusLeft.StPlusLeft
tโ‚'โœยน.P tโ‚‚โœ = tโ‚'โœ.P tโ‚‚โœ
;
x, yโ‚: Tm
nโœ: Nat
tโ‚‚โœ, tโ‚‚'โœยน: Tm
h: tโ‚‚โœ ~~> tโ‚‚'โœยน
hP: โˆ€ {yโ‚‚ : Tm}, tโ‚‚โœ ~~> yโ‚‚ โ†’ tโ‚‚'โœยน = yโ‚‚
tโ‚‚'โœ: Tm
h': tโ‚‚โœ ~~> tโ‚‚'โœ

StPlusRight.StPlusRight
(Tm.C nโœ).P tโ‚‚'โœยน = (Tm.C nโœ).P tโ‚‚'โœ
x, yโ‚: Tm
nโœ: Nat
tโ‚‚โœ, tโ‚‚'โœยน: Tm
h: tโ‚‚โœ ~~> tโ‚‚'โœยน
hP: โˆ€ {yโ‚‚ : Tm}, tโ‚‚โœ ~~> yโ‚‚ โ†’ tโ‚‚'โœยน = yโ‚‚
tโ‚‚'โœ: Tm
h': tโ‚‚โœ ~~> tโ‚‚'โœ

StPlusRight.StPlusRight
(Tm.C nโœ).P tโ‚‚'โœ = (Tm.C nโœ).P tโ‚‚'โœ

Goals accomplished! ๐Ÿ™

Goals accomplished! ๐Ÿ™
-- induction hyโ‚ generalizing yโ‚‚ with -- | StPlusConstConst => -- cases hyโ‚‚ <;> rename_i hโ‚‚ <;> first | rfl | cases hโ‚‚ -- -- cases hyโ‚‚ with -- -- | StPlusConstConst => rfl -- -- | StPlusLeft => -- -- rename_i hl -- -- cases hl -- -- | StPlusRight => -- -- rename_i hr -- -- cases hr -- | StPlusLeft => -- rename_i h hP -- cases hyโ‚‚ <;> first | contradiction | cases _ | (rename_i h'; rw [hP h']) -- -- rename_i hl hPl -- -- cases hyโ‚‚ with -- -- | StPlusConstConst => contradiction -- -- | StPlusLeft => -- -- rename_i hl' -- -- rw [hPl hl'] -- -- | StPlusRight => cases hl -- | StPlusRight => -- rename_i h hP -- cases hyโ‚‚ <;> first | contradiction | cases _ | (rename_i h'; rw [hP h']) -- -- rename_i hr hPr -- -- cases hyโ‚‚ with -- -- | StPlusConstConst => contradiction -- -- | StPlusLeft => -- -- rename_i hl' -- -- cases hl' -- -- | StPlusRight => -- -- rename_i hr' -- -- rw [hPr hr']

Goals accomplished! ๐Ÿ™