use fancy string notations
Open Scope string.
we'll use a binary representation of signed integers
Print Z.
Print positive.
Set Implicit Arguments.
Print positive.
Set Implicit Arguments.
quick review of fold
Fixpoint fold A B (f: A -> B -> B)
(l: list A) (b: B) :=
match l with
| nil => b
| x :: xs => f x (fold f xs b)
end.
(l: list A) (b: B) :=
match l with
| nil => b
| x :: xs => f x (fold f xs b)
end.
"+" can mean different things in different scopes
Locate "+".
Fixpoint countdown (n: nat) :=
match n with
| O => nil
| S m => Z_of_nat n :: countdown m
end.
Eval cbv in (countdown 5).
Eval cbv in (fold Z.add (countdown 5) 0%Z).
Eval cbv in (fold Z.add (countdown 12) 0%Z).
Fixpoint countdown (n: nat) :=
match n with
| O => nil
| S m => Z_of_nat n :: countdown m
end.
Eval cbv in (countdown 5).
Eval cbv in (fold Z.add (countdown 5) 0%Z).
Eval cbv in (fold Z.add (countdown 12) 0%Z).
fold + (3 :: 2 :: 1 :: nil) 0 ==> 3 + (2 + (1 + 0))
Could have also defined fact using Fixpoint:
AST
Fixpoint fact (n: nat) : nat := ...
Definition var := string.
Definition val := Z.
Inductive expr : Type :=
| Const : val -> expr
| Var : var -> expr
| Add : expr -> expr -> expr
| Mul : expr -> expr -> expr.
Inductive stmt : Type :=
| Skip : stmt
| Assign : var -> expr -> stmt
| Seq : stmt -> stmt -> stmt
| Cond : expr -> stmt -> stmt -> stmt
| While : expr -> stmt -> stmt.
switch to association lists for heaps
Definition heap := list (var * val).
Fixpoint lkup (k: var) (h: heap) :=
match h with
| nil => 0%Z
| (x, v) :: h' =>
if string_dec k x then v else lkup k h'
end.
Fixpoint lkup (k: var) (h: heap) :=
match h with
| nil => 0%Z
| (x, v) :: h' =>
if string_dec k x then v else lkup k h'
end.
fancy type containing proofs, but that acts like a bool
string_dec : forall s1 s2 : string, {s1 = s2} + {s1 <> s2}
Small Step Operational Semantics
Inductive Eval (h: heap) : expr -> val -> Prop :=
| EConst : forall n,
Eval h (Const n) n
| EVar : forall x,
Eval h (Var x) (lkup x h)
| EAdd : forall e1 e2 c1 c2 c3,
Eval h e1 c1 ->
Eval h e2 c2 ->
c3 = (c1 + c2)%Z ->
Eval h (Add e1 e2) c3
| EMul : forall e1 e2 c1 c2 c3,
Eval h e1 c1 ->
Eval h e2 c2 ->
c3 = (c1 * c2)%Z ->
Eval h (Mul e1 e2) c3.
| EConst : forall n,
Eval h (Const n) n
| EVar : forall x,
Eval h (Var x) (lkup x h)
| EAdd : forall e1 e2 c1 c2 c3,
Eval h e1 c1 ->
Eval h e2 c2 ->
c3 = (c1 + c2)%Z ->
Eval h (Add e1 e2) c3
| EMul : forall e1 e2 c1 c2 c3,
Eval h e1 c1 ->
Eval h e2 c2 ->
c3 = (c1 * c2)%Z ->
Eval h (Mul e1 e2) c3.
not every (heap, expr, Z) is related by Eval
the Eval relation has nothing to do with Eval command
Eval cbv in (countdown 5).
Inductive Step (h : heap)
: stmt -> heap -> stmt -> Prop :=
| SAssign : forall e c x,
Eval h e c ->
Step h (Assign x e) ((x, c) :: h) Skip
| SSeq1 : forall s,
Step h (Seq Skip s) h s
| SSeq2 : forall s1 s2 s1' h',
Step h s1 h' s1' ->
Step h (Seq s1 s2) h' (Seq s1' s2)
| SCondT : forall e c s1 s2,
Eval h e c ->
(c > 0)%Z ->
Step h (Cond e s1 s2) h s1
| SCondF : forall e c s1 s2,
Eval h e c ->
(c <= 0)%Z ->
Step h (Cond e s1 s2) h s2
| SWhileT : forall e c s,
Eval h e c ->
(c > 0)%Z ->
Step h (While e s) h (Seq s (While e s))
| SWhileF : forall e c s,
Eval h e c ->
(c <= 0)%Z ->
Step h (While e s) h Skip.
Inductive StepN : heap -> stmt -> nat ->
heap -> stmt -> Prop :=
| StepN_refl: forall h s,
StepN h s O h s
| StepN_step: forall h s n h' s' h'' s'',
Step h s h' s' ->
StepN h' s' n h'' s'' ->
StepN h s (S n) h'' s''.
Inductive Step (h : heap)
: stmt -> heap -> stmt -> Prop :=
| SAssign : forall e c x,
Eval h e c ->
Step h (Assign x e) ((x, c) :: h) Skip
| SSeq1 : forall s,
Step h (Seq Skip s) h s
| SSeq2 : forall s1 s2 s1' h',
Step h s1 h' s1' ->
Step h (Seq s1 s2) h' (Seq s1' s2)
| SCondT : forall e c s1 s2,
Eval h e c ->
(c > 0)%Z ->
Step h (Cond e s1 s2) h s1
| SCondF : forall e c s1 s2,
Eval h e c ->
(c <= 0)%Z ->
Step h (Cond e s1 s2) h s2
| SWhileT : forall e c s,
Eval h e c ->
(c > 0)%Z ->
Step h (While e s) h (Seq s (While e s))
| SWhileF : forall e c s,
Eval h e c ->
(c <= 0)%Z ->
Step h (While e s) h Skip.
Inductive StepN : heap -> stmt -> nat ->
heap -> stmt -> Prop :=
| StepN_refl: forall h s,
StepN h s O h s
| StepN_step: forall h s n h' s' h'' s'',
Step h s h' s' ->
StepN h' s' n h'' s'' ->
StepN h s (S n) h'' s''.
Divergance
Lemma diverges1:
forall h n, exists h', exists s',
StepN h (While (Const 1%Z) Skip) n h' s'.
Proof.
Admitted.
This page has been generated by coqdoc