-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathClase7.Imp.fst
105 lines (85 loc) · 3 KB
/
Clase7.Imp.fst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
module Clase7.Imp
open FStar.Mul
type var = string
type expr =
| Var : var -> expr
| Const : int -> expr
| Plus : expr -> expr -> expr
| Minus : expr -> expr -> expr
| Times : expr -> expr -> expr
| Eq : expr -> expr -> expr
type stmt =
| Assign : var -> expr -> stmt
| IfZ : expr -> stmt -> stmt -> stmt
| Seq : stmt -> stmt -> stmt
| Skip : stmt
| While : expr -> stmt -> stmt
type state = var -> int
let rec eval_expr (s : state) (e : expr) : int =
match e with
| Var x -> s x
| Const n -> n
| Plus e1 e2 -> eval_expr s e1 + eval_expr s e2
| Minus e1 e2 -> eval_expr s e1 - eval_expr s e2
| Times e1 e2 -> eval_expr s e1 * eval_expr s e2
| Eq e1 e2 -> if eval_expr s e1 = eval_expr s e2 then 0 else 1
let override (#a:eqtype) (#b:Type) (f : a -> b) (x:a) (y:b) : a -> b =
fun z -> if z = x then y else f z
(* Relación de evaluación big step. *)
noeq
type runsto : (p:stmt) -> (s0:state) -> (s1:state) -> Type0 =
| R_Skip : s:state -> runsto Skip s s
| R_Assign : s:state -> #x:var -> #e:expr -> runsto (Assign x e) s (override s x (eval_expr s e))
| R_Seq :
#p:stmt -> #q:stmt ->
#s:state -> #t:state -> #u:state ->
runsto p s t -> runsto q t u -> runsto (Seq p q) s u
| R_IfZ_True :
#c:expr -> #t:stmt -> #e:stmt ->
#s:state -> #s':state -> runsto t s s' ->
squash (eval_expr s c == 0) ->
runsto (IfZ c t e) s s'
| R_IfZ_False :
#c:expr -> #t:stmt -> #e:stmt ->
#s:state -> #s':state -> runsto e s s' ->
squash (eval_expr s c <> 0) ->
runsto (IfZ c t e) s s'
| R_While_True :
#c:expr -> #b:stmt -> #s:state -> #s':state -> #s'':state ->
runsto b s s' ->
squash (eval_expr s c = 0) ->
runsto (While c b) s' s'' ->
runsto (While c b) s s''
| R_While_False :
#c:expr -> #b:stmt -> #s:state ->
squash (eval_expr s c <> 0) ->
runsto (While c b) s s
// Demostrar que esta regla es admisible, es decir, que
// podemos "asumir" que la tenemos para demostrar, pero no
// necesitamos analizarla cuando destruímos una prueba:
//
// | R_While :
// #c:expr -> #b:stmt ->
// #s:state -> #s':state ->
// runsto (IfZ c (Seq b (While c b)) Skip) s s' ->
// runsto (While c b) s s'
let r_while (#c:expr) (#b:stmt) (#s #s' : state) (pf : runsto (IfZ c (Seq b (While c b)) Skip) s s')
: runsto (While c b) s s'
= admit()
type cond = state -> bool
noeq
type hoare : (pre:cond) -> (p:stmt) -> (post:cond) -> Type0 =
| H_Skip : pre:cond -> hoare pre Skip pre // {P} Skip {P}
| H_Seq :
#p:stmt -> #q:stmt ->
#pre:cond -> #mid:cond -> #post:cond ->
hoare pre p mid -> hoare mid q post ->
hoare pre (Seq p q) post // {pre} p {mid} /\ {mid} q {post} ==> {pre} p;q {post}
let rec hoare_ok (p:stmt) (pre:cond) (post:cond) (pf : hoare pre p post)
(s0 s1 : state) (e_pf : runsto p s0 s1)
: Lemma (requires pre s0)
(ensures post s1)
= admit()
let st0 : state = fun _ -> 0
let test1 : hoare (fun _ -> true) (Assign "x" (Const 1)) (fun s -> s "x" = 1) =
admit()