core - shaolintl/fstar-type-checker GitHub Wiki
Copied from http://prosecco.gforge.inria.fr/personal/hritcu/teaching/mpri-jan2017/
f ::= True | False | eβ == eβ | b2t e | fβ β§ fβ | ~f | β¦ (formulas)
c ::= Tot t | ST t (fun hβ -> fpre) (fun hβ x hβ -> fpost) (computation types)
t ::= unit | bool | int | ref int | heap | t -> c (types)
k ::= () | true | false | i | l | sel | upd | (=) | (<) | not | β¦(constants)
v ::= k | fun x -> e | rec (f:t) x -> e (values)
e ::= x | v | eβ eβ | if e then eβ else eβ !e | eβ := eβ | let x = eβ in eββ¦ (expressions)
Implicitly assumed everywhere
Ξ β’ True ok
Ξ β’ False ok
Ξ β’ eβ : Tot t Ξ β’ eβ : Tot t
βββββββββββββββββ
Ξ β’ (eβ == e2) ok
Ξ β’ e : Tot bool
βββββββββββββββββ
Ξ β’ (b2t e) ok
Ξ β’ fβ ok Ξ β’ fβ ok
ββββββββββββββ
Ξ β’ fβ β§ fβ ok
Ξ β’ f ok
βββββββββ
Ξ β’ ~f ok
Ξ β’ () : Tot unit
Ξ β’ true : Tot bool
Ξ β’ false : Tot bool
Ξ β’ i : Tot int
Ξ β’ l : Tot (ref int)
Ξ β’ sel : heap -> ref int -> Tot int
Ξ β’ upd : heap -> ref int -> int -> Tot heap
x:t β Ξ
βββββββββββββ (T-Var)
Ξ β’ x : Tot t
Ξ,x:t β’ e : c
ββββββββββββββββββββββββββββββββββ (T-Fun)
Ξ β’ fun x -> e : Tot (t -> c)
t = tβ -> c where c is not Tot Ξ,f:t,x:tβ β’ e : c
βββββββββββββββββββββββββββββββ (T-Rec)
Ξ β’ rec (f:t) x -> e : Tot t
Ξ β’ eβ : Tot (t -> c) Ξ β’ eβ : Tot t
βββββββββββββββββββββ (T-App)
Ξ β’ eβ eβ : c
Ξ β’ e : Tot bool Ξ β’ eβ : Tot t Ξ β’ eβ : Tot t
ββββββββββββββββββββββββββββββββ (T-IfTot)
Ξ β’ if e then eβ else eβ : Tot t
Ξ β’ e : Tot t
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ (T-Lift)
Ξ β’ e : ST t (fun hβ -> True) (fun hβ x hβ -> hβ == hβ β§ x == e)
Ξ β’ e : ST t (fun hβ -> fpre) (fun hβ x hβ -> fpost) Ξ β§ (βhβ. fpreβ β fpre) β§ (βhβ x hβ. fpost β fpostβ)
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ (T-Consequence)
Ξ β’ e : ST t (fun hβ -> fpreβ) (fun hβ x hβ -> fpostβ)
Ξ β’ e : Tot (ref int)
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ (T-Read)
Ξ β’ !e : ST int (fun hβ -> True) (fun hβ x hβ -> hβ == hβ β§ x == sel hβ e)
Ξ β’ eβ : Tot (ref int) Ξ β’ eβ : Tot int
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ (T-Update)
Ξ β’ eβ := eβ : ST unit (fun hβ -> True) (fun hβ () hβ -> hβ == upd hβ eβ eβ)
Ξ β’ e : Tot bool Ξ β’ eβ : ST t (fun hβ -> fpre β§ b2t e) (fun hβ x hβ -> fpost) Ξ β’ eβ : ST t (fun hβ -> fpre β§ ~b2t e) (fun hβ x hβ -> fpost)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ (T-IfST)
Ξ β’ if e then eβ else eβ : ST (fun hβ -> fpre) (fun hβ x hβ -> fpost)
Ξ β’ eβ : ST tβ (fun hβ -> fpreβ) (fun hβ xβ hβ -> fpostβ) Ξ,xβ:tβ β’ eβ : ST tβ (fun hβ -> fpreβ) (fun hβ xβ hβ -> fpostβ)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ (T-Let)
Ξ β’ let xβ = eβ in eβ : ST tβ (fun hβ -> fpreβ β§ βxβ hβ. fpostβ β fpreβ) (fun hβ xβ hβ -> fpreβ β βxβ hβ. fpostβ β§ (fpreβ β fpostβ))
val swap : rβ:ref int -> rβ:ref int -> ST unit (requires (fun hβ -> True)) (ensures (fun hβ _ hβ -> hβ == upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ))) let swap rβ rβ = let xβ = !rβ in let xβ = !rβ in let () = (rβ := xβ) in rβ := xβ
by (T-Read) Ξ β’ !rβ : ST int (fun hβ -> True) (fun hβ xβ hβ -> hβ == hβ β§ xβ == sel hβ rβ)
by (T-Read) Ξ,xβ:int β’ !rβ : ST int (fun hβ -> True) (fun hβ xβ hβ -> hβ == hβ β§ xβ == sel hβ rβ)
by (T-Update) Ξ,xβ:int,xβ:int β’ rβ := xβ : ST unit (fun hβ -> True) (fun hβ () hβ -> hβ == upd hβ rβ xβ)
by (T-Update) Ξ,xβ:int,xβ:int β’ rβ := xβ : ST unit (fun hβ -> True) (fun hβ () hβ -> hβ == upd hβ rβ xβ)
by (T-Let) Ξ,xβ:int,xβ:int β’ let _ = (rβ := xβ) in rβ := xβ : ST unit (fun hβ -> True) (fun hβ () hβ -> βhβ. hβ == upd hβ rβ xβ β§ hβ == upd hβ rβ xβ) by (T-Consequence) (fun hβ () hβ -> hβ == upd (upd hβ rβ xβ) rβ xβ)
by (T-Let) Ξ,xβ:int β’ let xβ = !rβ in (let _ = (rβ := xβ) in rβ := xβ) : ST unit (fun hβ -> True) (fun hβ () hβ -> βxβ hβ. hβ == hβ β§ xβ == sel hβ rβ β§ hβ == upd (upd hβ rβ xβ) rβ xβ) by (T-Consequence) (fun hβ () hβ -> hβ == upd (upd hβ rβ (sel hβ rβ)) rβ xβ)
by (T-Let) Ξ β’ let xβ = !rβ in (let xβ = !rβ in (let _ = (rβ := xβ) in rβ := xβ)) : ST unit (fun hβ -> True) (fun hβ () hβ -> βxβ hβ. hβ == hβ β§ xβ == sel hβ rβ β§ hβ == upd (upd hβ rβ (sel hβ rβ)) rβ xβ)
by (T-Consequence) val swap : rβ:ref int -> rβ:ref int -> ST unit (requires (fun hβ -> True)) (fun hβ () hβ -> hβ == upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ))
Ξ β§ (βhβ. True β True) β§ (βhβ x hβ. hβ == upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ) β sel hβ rβ = sel hβ rβ β§ sel hβ rβ = sel hβ rβ)
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ (T-Consequence)
val swap : rβ:ref int -> rβ:ref int -> ST unit (requires (fun hβ -> True)) (ensures (fun hβ _ hβ -> sel hβ rβ = sel hβ rβ β§ sel hβ rβ = sel hβ rβ))
- very intuitive specifications (Hoare logic)
- specs are clunkier to compose
- T-Let pushing preconditions backwards and postcondition forwards at the same time
- directional variants possible though
- hard to automate because of quantifier proliferation (each T-Let adds 4 quantifiers!)
- rules are hard to derive directly
wp, f ::= True | False | eβ == eβ | b2t e | fβ β§ fβ | ~f | β¦ p | fun x -> f | fun p -> f | fβ fβ | (wps and formulas)
c ::= Tot t | ST t wp (computation types)
Intuitively: postβ : t -> heap[final] -> Prop preβ : heap[initial] -> Prop wpβ : postβ -> Tot preβ
STβ t fpre fpost = ST t (fun p hβ -> fpre hβ β§ (βx hβ. fpost hβ x hβ β p x hβ))
For instance:
val swap : rβ:ref int -> rβ:ref int -> STβ unit (requires (fun hβ -> True)) (ensures (fun hβ _ hβ -> hβ == upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ))) becomes val swap : rβ:ref int -> rβ:ref int -> ST unit (fun p hβ -> βx hβ. hβ == upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ) β p x hβ) by (T-Consequence) (fun p hβ -> p () (upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ)))
And the same for a weaker spec:
val swap : rβ:ref int -> rβ:ref int -> STβ unit (requires (fun hβ -> True)) (ensures (fun hβ _ hβ -> sel hβ rβ = sel hβ rβ β§ sel hβ rβ = sel hβ rβ)) becomes val swap : rβ:ref int -> rβ:ref int -> ST unit (fun p hβ -> βhβ. sel hβ rβ = sel hβ rβ β§ sel hβ rβ = sel hβ rβ β p x hβ)
Ξ β’ e : Tot t
βββββββββββββββββββββββββββββββ (T-Lift)
Ξ β’ e : ST t (fun p h -> p e h)
Ξ β’ e : ST t wp Ξ β§ (βp h. wpβ p h β wp p h)
βββββββββββββββββββββββββββββ (T-Consequence)
Ξ β’ e : ST t wpβ
Ξ β’ e : Tot (ref int)
ββββββββββββββββββββββββββββββββββββββββββ (T-Read)
Ξ β’ !e : ST int (fun p h -> p (sel h e) h)
Ξ β’ eβ : Tot (ref int) Ξ β’ eβ : Tot int
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ (T-Update)
Ξ β’ eβ := eβ : ST unit (fun p h -> p () (upd h eβ eβ))
Ξ β’ eβ : ST tβ wpβ Ξ,xβ:tβ β’ eβ : ST tβ wpβ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ (T-Let)
Ξ β’ let xβ = eβ in eβ : ST tβ (fun p -> wpβ (fun xβ -> wpβ p))
Ξ β’ e : Tot bool Ξ β’ eβ : ST tβ wpβ Ξ β’ eβ : ST tβ wpβ
βββββββββββββββββββββββ-ββββββββββββββββββββββββββββββββββββββββββββββ (T-IfST)
Ξ β’ if e then eβ else eβ : ST tβ (fun p -> if e then wpβ p else wpβ p)
val swap : rβ:ref int -> rβ:ref int -> ST unit (fun p hβ -> p x (upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ))) let swap rβ rβ = hβ let xβ = !rβ in hβ let xβ = !rβ in hβ let () = (rβ := xβ) in hβ rβ := xβ hβ
by (T-Read) Ξ β’ !rβ : ST int (fun pβ hβ -> pβ (sel hβ rβ) hβ)
by (T-Read) Ξ,xβ:int β’ !rβ : ST int (fun pβ hβ -> pβ (sel hβ rβ) hβ)
by (T-Update) Ξ,xβ:int,xβ:int β’ rβ := xβ : ST unit (fun pβ hβ -> pβ () (upd hβ rβ xβ))
by (T-Update) Ξ,xβ:int,xβ:int β’ rβ := xβ : ST unit (fun pβ hβ -> pβ () (upd hβ rβ xβ))
by (T-Let) Ξ,xβ:int,xβ:int β’ let _ = (rβ := xβ) in rβ := xβ : ST unit (fun p -> (fun pβ hβ -> pβ () (upd hβ rβ xβ)) (fun _ -> (fun hβ -> p () (upd hβ rβ xβ)))) = (fun p hβ -> (fun _ -> (fun hβ -> p () (upd hβ rβ xβ))) () (upd hβ rβ xβ)) = (fun p hβ -> (fun hβ -> p () (upd hβ rβ xβ)) (upd hβ rβ xβ)) = (fun p hβ -> p () (upd (upd hβ rβ xβ) rβ xβ))
by (T-Let) Ξ,xβ:int β’ let xβ = !rβ in (let _ = (rβ := xβ) in rβ := xβ) : ST unit (fun p -> (fun pβ hβ -> pβ (sel hβ rβ) hβ) (fun xβ hβ -> p () (upd (upd hβ rβ xβ) rβ xβ))) = (fun p hβ -> (fun xβ hβ -> p () (upd (upd hβ rβ xβ) rβ xβ)) (sel hβ rβ) hβ) = (fun p hβ -> p () (upd (upd hβ rβ (sel hβ rβ)) rβ xβ))
by (T-Let) Ξ β’ let xβ = !rβ in (let xβ = !rβ in (let _ = (rβ := xβ) in rβ := xβ)) : ST unit (fun p -> (fun pβ hβ -> pβ (sel hβ rβ) hβ) (fun xβ hβ -> p () (upd (upd hβ rβ (sel hβ rβ)) rβ xβ))) = (fun p hβ -> (fun xβ hβ -> p () (upd (upd hβ rβ (sel hβ rβ)) rβ xβ)) (sel hβ rβ) hβ) = (fun p hβ -> p () (upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ)))
val swap : rβ:ref int -> rβ:ref int -> ST unit (fun p hβ -> p () (upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ)))
Ξ β§ (βp hβ. (βhβ. sel hβ rβ = sel hβ rβ β§ sel hβ rβ = sel hβ rβ β p () hβ) β p () (upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ)))
can instantiate premise for hβ = (upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ)) and show the conclusion
β (βp hβ. (sel (upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ)) rβ = sel hβ rβ β§ sel (upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ)) rβ = sel hβ rβ β p () (upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ))) β p () (upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ))) β (βp hβ. p () (upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ)) β p () (upd (upd hβ rβ (sel hβ rβ)) rβ (sel hβ rβ))) β True
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ (T-Consequence)
val swap : rβ:ref int -> rβ:ref int -> ST unit (fun p hβ -> βhβ. sel hβ rβ = sel hβ rβ β§ sel hβ rβ = sel hβ rβ β p x hβ)
val factorial_tot : nat -> Tot nat let rec factorial_tot x = if x = 0 then 1 else x * factorial_tot (x - 1)
val factorial : rβ:ref nat -> rβ:ref nat -> ST unit (requires (fun hβ -> True)) (ensures (fun hβ a hβ -> βx. hβ == (upd (upd hβ rβ x) rβ (factorial_tot (sel hβ rβ)))))
- which desugars to:
val factorial : rβ:ref nat -> rβ:ref nat -> ST unit (fun p hβ -> βhβ. βx. hβ == (upd (upd hβ rβ x) rβ (factorial_tot (sel hβ rβ))) β p () hβ)
- which is equivalent to
val factorial : rβ:ref nat -> rβ:ref nat -> ST unit (fun p hβ -> βx. p () (upd (upd hβ rβ x) rβ (factorial_tot (sel hβ rβ))))
let rec factorial rβ rβ = hβ let xβ = !rβ in hβ if xβ = 0 then rβ := 1 hβ else (rβ := xβ - 1; hβ factorial rβ rβ; hβ let xβ = !rβ in hβ rβ := xβ * xβ) hβ
by (T-Update) rβ : ref int, rβ : ref int, xβ:int, xβ:int β’ rβ := xβ * xβ : ST unit (fun pβ hβ -> pβ () (upd hβ rβ (xβ * xβ)))
by (T-Read) rβ : ref int, rβ : ref int, xβ:int β’ !rβ : ST int (fun pβ hβ -> pβ (sel hβ rβ) hβ)
by (T-Let) rβ : ref int, rβ : ref int, xβ:int β’ (let xβ = !rβ in rβ := xβ * xβ) : ST (fun p -> (fun pβ hβ -> pβ (sel hβ rβ) hβ) (fun xβ hβ -> p () (upd hβ rβ (xβ * xβ)))) = (fun p hβ -> (fun xβ hβ -> p () (upd hβ rβ (xβ * xβ))) (sel hβ rβ) hβ) = (fun p hβ -> p () (upd hβ rβ (sel hβ rβ * xβ)))
by (T-App) rβ : ref int, rβ : ref int, xβ:int β’ factorial rβ rβ : ST unit (fun pβ hβ -> βx. pβ () (upd (upd hβ rβ x) rβ (factorial_tot (sel hβ rβ))))
by (T-Let) rβ : ref int, rβ : ref int, xβ:int β’ (factorial rβ rβ; let xβ = !rβ in rβ := xβ * xβ) : ST unit (fun p -> (fun pβ hβ -> βx. pβ () (upd (upd hβ rβ x) rβ (factorial_tot (sel hβ rβ)))) (fun _ hβ -> p () (upd hβ rβ (sel hβ rβ * xβ)))) = (fun p hβ -> βx. (fun hβ -> p () (upd hβ rβ (sel hβ rβ * xβ))) (upd (upd hβ rβ x) rβ (factorial_tot (sel hβ rβ)))) = (fun p hβ -> βx. p () (upd (upd (upd hβ rβ x) rβ (factorial_tot (sel hβ rβ))) rβ (sel (upd (upd hβ rβ x) rβ (factorial_tot (sel hβ rβ))) rβ * xβ))) β (fun p hβ -> βx. p () (upd (upd (upd hβ rβ x) rβ (factorial_tot (sel hβ rβ))) rβ (factorial_tot (sel hβ rβ)) * xβ)) β (fun p hβ -> βx. p () (upd (upd hβ rβ x) rβ (factorial_tot (sel hβ rβ)) * xβ))
by (T-Update) rβ : ref int, rβ : ref int, xβ:int β’ rβ := xβ - 1 : ST unit (fun pβ hβ -> pβ () (upd hβ rβ (xβ-1)))
by (T-Let) rβ : ref int, rβ : ref int, xβ:int β’ (rβ := xβ - 1; factorial rβ rβ; let xβ = !rβ in rβ := xβ * xβ) : ST unit (fun p -> (fun pβ hβ -> pβ () (upd hβ rβ (xβ-1))) (fun _ hβ -> βx. p () (upd (upd hβ rβ x) rβ (factorial_tot (sel hβ rβ)) * xβ))) = (fun p hβ -> βx. p () (upd (upd (upd hβ rβ (xβ-1)) rβ x) rβ (factorial_tot (sel (upd hβ rβ (xβ-1)) rβ)) * xβ)) β (fun p hβ -> βx. p () (upd (upd hβ rβ x) rβ (factorial_tot (xβ-1)) * xβ))
by (T-Update) rβ : ref int, rβ : ref int, xβ:int β’ rβ := 1 : ST unit (fun p hβ -> p () (upd hβ rβ 1))
by (T-IfST) rβ : ref int, rβ : ref int, xβ:int β’(if xβ = 0 then rβ := 1 else rβ := xβ - 1; factorial rβ rβ; let xβ = !rβ in rβ := xβ * xβ) : ST unit (fun p -> if xβ = 0 then (fun hβ -> p () (upd hβ rβ 1)) else (fun hβ -> βx. p () (upd (upd hβ rβ x) rβ (factorial_tot (xβ-1)) * xβ)))
by (T-Read) rβ : ref int, rβ : ref int, xβ:int β’ !rβ : ST int (fun pβ hβ -> pβ (sel hβ rβ) hβ)
by (T-Let) rβ : ref int, rβ : ref int β’ factorial_body : ST (fun p -> (fun pβ hβ -> pβ (sel hβ rβ) hβ) (fun xβ -> if xβ = 0 then (fun hβ -> p () (upd hβ rβ 1)) else (fun hβ -> βx. p () (upd (upd hβ rβ x) rβ (factorial_tot (xβ-1)) * xβ)))) = (fun p hβ -> if sel hβ rβ = 0 then p () (upd hβ rβ 1) else βx. p () (upd (upd hβ rβ x) rβ (factorial_tot (sel hβ rβ - 1)) * (sel hβ rβ))) β (fun p hβ -> βx. p () (upd (upd hβ rβ x) rβ (factorial_tot (sel hβ rβ))))
What do Dijkstra monads say in this case? Convert triples to WPs and use WP bind β¦ what does one get?
STβ t pre post = ST t (fun p hβ -> pre hβ β§ (β x hβ. post hβ x hβ β p x hβ))
Ξ β’ eβ : STβ tβ (fun hβ -> fpreβ) (fun hβ xβ hβ -> fpostβ) Ξ,xβ:tβ β’ eβ : STβ tβ (fun hβ -> fpreβ) (fun hβ xβ hβ -> fpostβ)
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ (T-Let)
Ξ β’ let xβ = eβ in eβ : STβ tβ (fun hβ -> fpre) (fun hβ x hβ -> fpost)
Ξ β’ eβ : ST tβ (fun post hβ -> fpreβ hβ β§ βxβ hβ. fpostβ hβ xβ hβ β post xβ hβ) = wpβ Ξ,xβ:tβ β’ eβ : ST tβ (fun post hβ -> fpreβ hβ β§ βxβ hβ. fpostβ hβ xβ hβ β post xβ hβ) = wpβ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ (T-Let) Ξ β’ let xβ = eβ in eβ : ST tβ wp
The WP-based (T-Let) rule works like this: Ξ β’ let xβ = eβ in eβ : ST tβ (bindββ x β wpβ in wpβ) Ξ β’ let xβ = eβ in eβ : ST tβ (fun post hβ -> wpβ (fun x hβ -> wpβ post hβ) hβ) if we plug in the WPs above we get: Ξ β’ let xβ = eβ in eβ : ST tβ (fun post hβ -> (fun post hβ -> fpreβ hβ β§ βxβ hβ. fpostβ hβ xβ hβ β post xβ hβ) (fun xβ hβ -> (fun post hβ -> fpreβ hβ β§ βxβ hβ. fpostβ hβ xβ hβ β post xβ hβ) post hβ) hβ) = ST t2 (fun post hβ -> fpreβ hβ β§ βxβ hβ. fpostβ hβ xβ hβ β fpreβ hβ β§ βxβ hβ. fpostβ hβ xβ hβ β post xβ hβ) = wp
- this already allows us to derive fpre fpre = wp (fun x h -> True) = fpreβ hβ β§ βxβ hβ. fpostβ hβ xβ hβ β fpreβ hβ
- and fpost too using the following relation:
let as_ensures (#a:Type) (wp:st_wp a) = fun hβ x hβ -> ~(wp (fun xβ hββ -> x=!=xβ \/ hβ=!=hββ) hβ)
fpost hβ xβ hβ = ~( (fun post hβ -> fpreβ hβ β§ βxβ hβ. fpostβ hβ xβ hβ β fpreβ hβ β§ βxβ hβ. fpostβ hβ xβ hβ β post xβ hβ) (fun xββ hββ -> xββ
!=xβ \/ hβ'
!=hβ) hβ ) = ~ (fpreβ hβ β§ (βxβ hβ. fpostβ hβ xβ hβ β (fpreβ hβ β§ βxββ hββ. fpostβ hβ xβ hβ β xβ=!=xββ β¨ hβ=!=hββ))) = fpreβ hβ β (βxβ hβ. fpostβ hβ xβ hβ β§ ~(fpreβ hβ β§ βxββ hββ. fpostβ hβ xβ hβ β xβ=!=xββ β¨ hβ=!=hββ))) = fpreβ hβ β βxβ hβ. fpostβ hβ xβ hβ β§ (fpreβ hβ β βxββ hββ. fpostβ hβ xβ hβ β§ xβ==xββ β§ hβ==hββ) = fpreβ hβ β βxβ hβ. fpostβ hβ xβ hβ β§ (fpreβ hβ β fpostβ hβ xβ hβ)Ξ β’ eβ : ST tβ (fun hβ -> fpreβ) (fun hβ xβ hβ -> fpostβ)
Ξ,xβ:tβ β’ eβ : ST tβ (fun hβ -> fpreβ) (fun hβ xβ hβ -> fpostβ)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ (T-Let)
Ξ β’ let xβ = eβ in eβ : ST tβ (fun hβ -> fpreβ hβ β§ βxβ hβ. fpostβ hβ xβ hβ β fpreβ hβ) (fun hβ xβ hβ -> fpreβ hβ β βxβ hβ. fpostβ hβ xβ hβ β§ (fpreβ hβ β fpostβ hβ xβ hβ))
Ξ β’ eβ : ST tβ (fun hβ -> fpreβ) (fun hβ xβ hβ -> fpostβ) Ξ,xβ:tβ β’ eβ : ST tβ (fun hβ -> fpreβ) (fun hβ xβ hβ -> fpostβ)
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ (T-Let template)
Ξ β’ let xβ = eβ in eβ : STβ tβ (fun hβ -> fpre) (fun hβ xβ hβ -> fpost) = ST tβ (fun p hβ -> fpre hβ β§ (βxβ hβ. fpost hβ xβ hβ β p xβ hβ))
Ξ β’ eβ : ST tβ (fun post hβ -> fpreβ hβ β§ βxβ hβ. fpostβ hβ xβ hβ β post xβ hβ) = wpβ Ξ,xβ:tβ β’ eβ : ST tβ (fun post hβ -> fpreβ hβ β§ βxβ hβ. fpostβ hβ xβ hβ β post xβ hβ) = wpβ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ (T-Let on WPs)
Ξ β’ let xβ = eβ in eβ : ST tβ (fun p hβ -> fpreβ hβ β§ (βxβ hβ. fpostβ hβ xβ hβ β fpreβ hβ β§ βxβ hβ. fpostβ hβ xβ hβ β p xβ hβ))
Problem: find fpreβ, fpostβ, fpreβ, fpostβ in terms of fpre and fpost so that (fpre hβ β§ (βxβ hβ. fpost hβ xβ hβ β p xβ hβ)) β (fpreβ hβ β§ (βxβ hβ. fpostβ hβ xβ hβ β fpreβ hβ β§ βxβ hβ. fpostβ hβ xβ hβ β p xβ hβ))
First step is easy: fpreβ = fpre Might need to keep fpostβ (in hoare there is also a magic interpolant) Can I derive fpreβ from fpostβ? For instance: fpreβ = βhβ. fpostβ hβ Can I derive fpostβ from fpost? from previous derivation we had fpost = fpre β βxβ hβ. fpostβ β§ (fpreβ β fpostβ)
β¦ not there yet β¦