ImpShort
Imp Syntax
c := skip | x := a | c ; c | if b then c else c end
| while b do c end
Inductive com : Type :=
| CSkip
| CAsgn (x : string) (a : aexp)
| CSeq (c1 c2 : com)
| CIf (b : bexp) (c1 c2 : com)
| CWhile (b : bexp) (c : com).
| CSkip
| CAsgn (x : string) (a : aexp)
| CSeq (c1 c2 : com)
| CIf (b : bexp) (c1 c2 : com)
| CWhile (b : bexp) (c : com).
Definition fact_in_coq : com :=
<{ Z := X;
Y := 1;
while Z ≠ 0 do
Y := Y × Z;
Z := Z - 1
end }>.
<{ Z := X;
Y := 1;
while Z ≠ 0 do
Y := Y × Z;
Z := Z - 1
end }>.
See Coq devlopment
Evaluation as a Function (Failed Attempt)
Fixpoint denote (c : com) (st : mem) : mem :=
match c with
| <{ skip }> ⇒
st
| <{ x := a }> ⇒
(x !-> (aeval st a) ; st)
| <{ c1 ; c2 }> ⇒
let st' := denote c1 st in
let st'' := denote c2 st' in
st''
| <{ if b then c1 else c2 end}> ⇒
if (beval st b)
then denote c1 st
else denote c2 st
| <{ while b do c end }> ⇒
st (* bogus! *)
end.
match c with
| <{ skip }> ⇒
st
| <{ x := a }> ⇒
(x !-> (aeval st a) ; st)
| <{ c1 ; c2 }> ⇒
let st' := denote c1 st in
let st'' := denote c2 st' in
st''
| <{ if b then c1 else c2 end}> ⇒
if (beval st b)
then denote c1 st
else denote c2 st
| <{ while b do c end }> ⇒
st (* bogus! *)
end.
Relational Operational Semantics
(E_Skip) | |
st =[ skip ]=> st |
aeval st a = n | (E_Asgn) |
st =[ x := a ]=> (x !-> n ; st) |
st =[ c1 ]=> st' | |
st' =[ c2 ]=> st'' | (E_Seq) |
st =[ c1;c2 ]=> st'' |
beval st b = true | |
st =[ c1 ]=> st' | (E_IfTrue) |
st =[ if b then c1 else c2 end ]=> st' |
beval st b = false | |
st =[ c2 ]=> st' | (E_IfFalse) |
st =[ if b then c1 else c2 end ]=> st' |
beval st b = false | (E_WhileFalse) |
st =[ while b do c end ]=> st |
beval st b = true | |
st =[ c ]=> st' | |
st' =[ while b do c end ]=> st'' | (E_WhileTrue) |
st =[ while b do c end ]=> st'' |
Inductive ceval : com → mem → mem → Prop :=
| E_Skip : ∀ st,
st =[ skip ]=> st
| E_Asgn : ∀ st a n x,
aeval st a = n →
st =[ x := a ]=> (x !-> n ; st)
| E_Seq : ∀ c1 c2 st st' st'',
st =[ c1 ]=> st' →
st' =[ c2 ]=> st'' →
st =[ c1 ; c2 ]=> st''
| E_IfTrue : ∀ st st' b c1 c2,
beval st b = true →
st =[ c1 ]=> st' →
st =[ if b then c1 else c2 end]=> st'
| E_IfFalse : ∀ st st' b c1 c2,
beval st b = false →
st =[ c2 ]=> st' →
st =[ if b then c1 else c2 end]=> st'
| E_WhileFalse : ∀ b st c,
beval st b = false →
st =[ while b do c end ]=> st
| E_WhileTrue : ∀ st st' st'' b c,
beval st b = true →
st =[ c ]=> st' →
st' =[ while b do c end ]=> st'' →
st =[ while b do c end ]=> st''
where "st =[ c ]=> st'" := (ceval c st st').
| E_Skip : ∀ st,
st =[ skip ]=> st
| E_Asgn : ∀ st a n x,
aeval st a = n →
st =[ x := a ]=> (x !-> n ; st)
| E_Seq : ∀ c1 c2 st st' st'',
st =[ c1 ]=> st' →
st' =[ c2 ]=> st'' →
st =[ c1 ; c2 ]=> st''
| E_IfTrue : ∀ st st' b c1 c2,
beval st b = true →
st =[ c1 ]=> st' →
st =[ if b then c1 else c2 end]=> st'
| E_IfFalse : ∀ st st' b c1 c2,
beval st b = false →
st =[ c2 ]=> st' →
st =[ if b then c1 else c2 end]=> st'
| E_WhileFalse : ∀ b st c,
beval st b = false →
st =[ while b do c end ]=> st
| E_WhileTrue : ∀ st st' st'' b c,
beval st b = true →
st =[ c ]=> st' →
st' =[ while b do c end ]=> st'' →
st =[ while b do c end ]=> st''
where "st =[ c ]=> st'" := (ceval c st st').
Some observations
- specifying Imp program behaviors
- is partial: there is no resulting mem for a diverging program
- isn't structural: the E_WhileTrue rule is defined in terms of itself
- isn't executable: we can't extract this as a program (no QuickChick!)
- is a deep embedding: no re-use of meta-level (Coq) functionality