Annotate while with invariants in the language
This commit is contained in:
parent
4f15160760
commit
3888b62c6a
1 changed files with 48 additions and 46 deletions
94
wp.v
94
wp.v
|
@ -11,13 +11,26 @@ Definition Var := nat.
|
||||||
Definition Mem := Var -> Z.
|
Definition Mem := Var -> Z.
|
||||||
Definition Expr:= Mem -> Z.
|
Definition Expr:= Mem -> Z.
|
||||||
|
|
||||||
|
Inductive SynAssert : Type:=
|
||||||
|
| ATop: SynAssert
|
||||||
|
| ABot: SynAssert
|
||||||
|
| ANeg: SynAssert -> SynAssert
|
||||||
|
| AAnd: SynAssert -> SynAssert -> SynAssert
|
||||||
|
| AOr: SynAssert -> SynAssert -> SynAssert
|
||||||
|
| AImplies: SynAssert -> SynAssert -> SynAssert
|
||||||
|
| AExpr: Expr -> SynAssert
|
||||||
|
| AForall: Var -> SynAssert -> SynAssert
|
||||||
|
| AExists: Var -> SynAssert -> SynAssert
|
||||||
|
| ASubstZ: Var -> Z -> SynAssert -> SynAssert
|
||||||
|
| ASubstE: Var -> Expr -> SynAssert -> SynAssert.
|
||||||
|
|
||||||
Inductive Instr : Type :=
|
Inductive Instr : Type :=
|
||||||
| skip: Instr
|
| skip: Instr
|
||||||
| abort: Instr
|
| abort: Instr
|
||||||
| assign: Var -> Expr -> Instr
|
| assign: Var -> Expr -> Instr
|
||||||
| seq: Instr -> Instr -> Instr
|
| seq: Instr -> Instr -> Instr
|
||||||
| ifelse: Expr -> Instr -> Instr -> Instr
|
| ifelse: Expr -> Instr -> Instr -> Instr
|
||||||
| while: Expr -> Instr -> Instr.
|
| while: SynAssert -> Expr -> Instr -> Instr.
|
||||||
|
|
||||||
Definition ifonly (exp: Expr) (inst: Instr) : Instr :=
|
Definition ifonly (exp: Expr) (inst: Instr) : Instr :=
|
||||||
ifelse exp inst skip.
|
ifelse exp inst skip.
|
||||||
|
@ -87,7 +100,7 @@ Fixpoint interp (inst: Instr) (mem: MemCpo) : MemCpo :=
|
||||||
if ((guard mem0) =? 0) % Z
|
if ((guard mem0) =? 0) % Z
|
||||||
then interp instrElse mem
|
then interp instrElse mem
|
||||||
else interp instrIf mem
|
else interp instrIf mem
|
||||||
| while guard body =>
|
| while _ guard body =>
|
||||||
let fix while_chain (mem: MemCpo) (n: nat): MemCpo :=
|
let fix while_chain (mem: MemCpo) (n: nat): MemCpo :=
|
||||||
match n with
|
match n with
|
||||||
| 0 => mem
|
| 0 => mem
|
||||||
|
@ -129,16 +142,16 @@ Definition expr_neg (expr: Expr) : Expr :=
|
||||||
| _ => 0%Z
|
| _ => 0%Z
|
||||||
end.
|
end.
|
||||||
|
|
||||||
Lemma certain_termination_exists body guard mem :
|
Lemma certain_termination_exists assert body guard mem :
|
||||||
interp (while guard body) mem <> MemError ->
|
interp (while assert guard body) mem <> MemError ->
|
||||||
exists n: nat,
|
exists n: nat,
|
||||||
interp (nth_iterate (ifonly guard body) n) mem |=e expr_neg guard.
|
interp (nth_iterate (ifonly guard body) n) mem |=e expr_neg guard.
|
||||||
Proof.
|
Proof.
|
||||||
intros noError.
|
intros noError.
|
||||||
Admitted.
|
Admitted.
|
||||||
|
|
||||||
Lemma certain_termination_exists_minimal body guard mem :
|
Lemma certain_termination_exists_minimal assert body guard mem :
|
||||||
interp (while guard body) mem <> MemError ->
|
interp (while assert guard body) mem <> MemError ->
|
||||||
exists n: nat,
|
exists n: nat,
|
||||||
(forall p: nat, p < n ->
|
(forall p: nat, p < n ->
|
||||||
interp (nth_iterate (ifonly guard body) p) mem |=e guard)
|
interp (nth_iterate (ifonly guard body) p) mem |=e guard)
|
||||||
|
@ -147,15 +160,15 @@ Proof.
|
||||||
intros not_error.
|
intros not_error.
|
||||||
Admitted.
|
Admitted.
|
||||||
|
|
||||||
Lemma certain_termination body guard mem :
|
Lemma certain_termination assert body guard mem :
|
||||||
interp (while guard body) mem <> MemError ->
|
interp (while assert guard body) mem <> MemError ->
|
||||||
exists n: nat,
|
exists n: nat,
|
||||||
(interp (nth_iterate body n) mem) |=e (expr_neg guard)
|
(interp (nth_iterate body n) mem) |=e (expr_neg guard)
|
||||||
/\ (forall p, p < n -> (interp (nth_iterate body p) mem) |=e guard)
|
/\ (forall p, p < n -> (interp (nth_iterate body p) mem) |=e guard)
|
||||||
/\ interp (while guard body) mem = interp (nth_iterate body n) mem.
|
/\ interp (while assert guard body) mem = interp (nth_iterate body n) mem.
|
||||||
Proof.
|
Proof.
|
||||||
intros notError.
|
intros notError.
|
||||||
elim (certain_termination_exists_minimal body guard mem).
|
elim (certain_termination_exists_minimal assert body guard mem).
|
||||||
intros n. intros [notBeforeN atN]. exists n.
|
intros n. intros [notBeforeN atN]. exists n.
|
||||||
split.
|
split.
|
||||||
Admitted.
|
Admitted.
|
||||||
|
@ -240,9 +253,9 @@ Inductive hoare_provability : Assert -> Instr -> Assert -> Prop :=
|
||||||
(|- [| pre /\ ~(assertOfExpr expr) |] sElse [| post |]) % assert ->
|
(|- [| pre /\ ~(assertOfExpr expr) |] sElse [| post |]) % assert ->
|
||||||
(|- [| pre |] (ifelse expr sIf sElse) [| post |]) % assert
|
(|- [| pre |] (ifelse expr sIf sElse) [| post |]) % assert
|
||||||
| H_while:
|
| H_while:
|
||||||
forall inv, forall expr, forall sBody,
|
forall inv assert expr sBody,
|
||||||
(|- [| inv /\ (assertOfExpr expr) |] sBody [| inv |]) % assert ->
|
(|- [| inv /\ (assertOfExpr expr) |] sBody [| inv |]) % assert ->
|
||||||
(|- [| inv |] (while expr sBody)
|
(|- [| inv |] (while assert expr sBody)
|
||||||
[| inv /\ ~ (assertOfExpr expr) |]) % assert
|
[| inv /\ ~ (assertOfExpr expr) |]) % assert
|
||||||
where "|- [| pre |] instr [| post |]" :=
|
where "|- [| pre |] instr [| post |]" :=
|
||||||
(hoare_provability pre instr post) : assert.
|
(hoare_provability pre instr post) : assert.
|
||||||
|
@ -390,9 +403,9 @@ Proof.
|
||||||
+ assumption.
|
+ assumption.
|
||||||
+ rewrite <- Z.eqb_eq. congruence.
|
+ rewrite <- Z.eqb_eq. congruence.
|
||||||
- unfold conseq_or_bottom.
|
- unfold conseq_or_bottom.
|
||||||
destruct (interp (while expr sBody) (MemElem mem)) eqn:interpRel.
|
destruct (interp (while assert expr sBody) (MemElem mem)) eqn:interpRel.
|
||||||
* trivial.
|
* trivial.
|
||||||
* elim (certain_termination sBody expr (MemElem mem)).
|
* elim (certain_termination assert sBody expr (MemElem mem)).
|
||||||
intros n [lastIter [notLastIter isWhile] ].
|
intros n [lastIter [notLastIter isWhile] ].
|
||||||
rewrite isWhile in interpRel.
|
rewrite isWhile in interpRel.
|
||||||
destruct n.
|
destruct n.
|
||||||
|
@ -440,6 +453,23 @@ Proof.
|
||||||
+ rewrite interpRel; unfold MemError; congruence.
|
+ rewrite interpRel; unfold MemError; congruence.
|
||||||
Qed.
|
Qed.
|
||||||
|
|
||||||
|
(***** Syntactic assertion interpretation ************************************)
|
||||||
|
|
||||||
|
Fixpoint aInterp (src: SynAssert): Assert :=
|
||||||
|
fun (mem: Mem) => match src with
|
||||||
|
| ATop => True
|
||||||
|
| ABot => False
|
||||||
|
| ANeg x => ~ (aInterp x mem)
|
||||||
|
| AAnd x y => (aInterp x mem) /\ (aInterp y mem)
|
||||||
|
| AOr x y => (aInterp x mem) \/ (aInterp y mem)
|
||||||
|
| AImplies x y => (~ (aInterp x mem)) \/ (aInterp y mem)
|
||||||
|
| AExpr exp => exp mem <> 0%Z
|
||||||
|
| AForall v x => forall (z: Z), aInterp x (mem [v <- z])
|
||||||
|
| AExists v x => exists (z: Z), aInterp x (mem [v <- z])
|
||||||
|
| ASubstZ v z x => aInterp x (mem [v <- z])
|
||||||
|
| ASubstE v e x => aInterp x (mem [v <- (e mem)])
|
||||||
|
end.
|
||||||
|
|
||||||
(***** Weakest precondition **************************************************)
|
(***** Weakest precondition **************************************************)
|
||||||
|
|
||||||
Fixpoint wp (instr: Instr) (cond: Assert) : Assert := match instr with
|
Fixpoint wp (instr: Instr) (cond: Assert) : Assert := match instr with
|
||||||
|
@ -450,7 +480,7 @@ Fixpoint wp (instr: Instr) (cond: Assert) : Assert := match instr with
|
||||||
| ifelse guard sIf sElse =>
|
| ifelse guard sIf sElse =>
|
||||||
((assertOfExpr guard -> wp sIf cond)
|
((assertOfExpr guard -> wp sIf cond)
|
||||||
/\ (~ (assertOfExpr guard) -> wp sElse cond)) % assert
|
/\ (~ (assertOfExpr guard) -> wp sElse cond)) % assert
|
||||||
| while guard body => assertBot
|
| while assert guard body => assertBot
|
||||||
end.
|
end.
|
||||||
|
|
||||||
Lemma assertImplElim {a b: Assert} :
|
Lemma assertImplElim {a b: Assert} :
|
||||||
|
@ -527,7 +557,7 @@ Proof.
|
||||||
* apply (H_conseq
|
* apply (H_conseq
|
||||||
assertBot post
|
assertBot post
|
||||||
assertBot (assertBot /\ ~ (assertOfExpr e))%assert).
|
assertBot (assertBot /\ ~ (assertOfExpr e))%assert).
|
||||||
- apply (H_while assertBot e instr).
|
- apply (H_while assertBot s e instr).
|
||||||
apply (H_conseq
|
apply (H_conseq
|
||||||
(assertBot /\ assertOfExpr e)%assert assertBot
|
(assertBot /\ assertOfExpr e)%assert assertBot
|
||||||
assertBot assertBot).
|
assertBot assertBot).
|
||||||
|
@ -585,35 +615,7 @@ Proof.
|
||||||
apply wp_correctness_provable.
|
apply wp_correctness_provable.
|
||||||
Qed.
|
Qed.
|
||||||
|
|
||||||
(***** Assertions syntaxiques******** ****************************************)
|
(***** Assertions syntaxiques -- proprietes **********************************)
|
||||||
|
|
||||||
Inductive SynAssert : Type:=
|
|
||||||
| ATop: SynAssert
|
|
||||||
| ABot: SynAssert
|
|
||||||
| ANeg: SynAssert -> SynAssert
|
|
||||||
| AAnd: SynAssert -> SynAssert -> SynAssert
|
|
||||||
| AOr: SynAssert -> SynAssert -> SynAssert
|
|
||||||
| AImplies: SynAssert -> SynAssert -> SynAssert
|
|
||||||
| AExpr: Expr -> SynAssert
|
|
||||||
| AForall: Var -> SynAssert -> SynAssert
|
|
||||||
| AExists: Var -> SynAssert -> SynAssert
|
|
||||||
| ASubstZ: Var -> Z -> SynAssert -> SynAssert
|
|
||||||
| ASubstE: Var -> Expr -> SynAssert -> SynAssert.
|
|
||||||
|
|
||||||
Fixpoint aInterp (src: SynAssert): Assert :=
|
|
||||||
fun (mem: Mem) => match src with
|
|
||||||
| ATop => True
|
|
||||||
| ABot => False
|
|
||||||
| ANeg x => ~ (aInterp x mem)
|
|
||||||
| AAnd x y => (aInterp x mem) /\ (aInterp y mem)
|
|
||||||
| AOr x y => (aInterp x mem) \/ (aInterp y mem)
|
|
||||||
| AImplies x y => (~ (aInterp x mem)) \/ (aInterp y mem)
|
|
||||||
| AExpr exp => exp mem <> 0%Z
|
|
||||||
| AForall v x => forall (z: Z), aInterp x (mem [v <- z])
|
|
||||||
| AExists v x => exists (z: Z), aInterp x (mem [v <- z])
|
|
||||||
| ASubstZ v z x => aInterp x (mem [v <- z])
|
|
||||||
| ASubstE v e x => aInterp x (mem [v <- (e mem)])
|
|
||||||
end.
|
|
||||||
|
|
||||||
Fixpoint wps (instr: Instr) (asser: SynAssert) : SynAssert := match instr with
|
Fixpoint wps (instr: Instr) (asser: SynAssert) : SynAssert := match instr with
|
||||||
| skip => asser
|
| skip => asser
|
||||||
|
@ -624,7 +626,7 @@ Fixpoint wps (instr: Instr) (asser: SynAssert) : SynAssert := match instr with
|
||||||
AAnd
|
AAnd
|
||||||
(AImplies (AExpr guard) (wps sIf asser))
|
(AImplies (AExpr guard) (wps sIf asser))
|
||||||
(AImplies (ANeg (AExpr guard)) (wps sElse asser))
|
(AImplies (ANeg (AExpr guard)) (wps sElse asser))
|
||||||
| while guard body => ABot
|
| while assert guard body => ABot
|
||||||
end.
|
end.
|
||||||
|
|
||||||
Lemma aInterpConsistent (instr: Instr):
|
Lemma aInterpConsistent (instr: Instr):
|
||||||
|
|
Loading…
Reference in a new issue