1
|
open Spec_types
|
2
|
open Utils
|
3
|
|
4
|
(* a small reduction engine *)
|
5
|
let is_true = function True -> true | _ -> false
|
6
|
|
7
|
let is_false = function False -> true | _ -> false
|
8
|
|
9
|
let type_of_value = function
|
10
|
| Val v -> v.Machine_code_types.value_type
|
11
|
| Tag (_, t) -> t
|
12
|
| Var v ->
|
13
|
v.var_type
|
14
|
| Memory ResetFlag ->
|
15
|
Type_predef.type_bool
|
16
|
| Memory (StateVar v) ->
|
17
|
v.var_type
|
18
|
|
19
|
let expr_eq a b = a = b
|
20
|
(* match a, b with *)
|
21
|
(* | Var x, Var y -> *)
|
22
|
(* x = y *)
|
23
|
(* | Memory r1, Memory r2 -> *)
|
24
|
(* r1 = r2 *)
|
25
|
(* | _ -> *)
|
26
|
(* false *)
|
27
|
|
28
|
let rec red = function
|
29
|
| Equal (a, b) when expr_eq a b ->
|
30
|
True
|
31
|
| And l -> (
|
32
|
let l' =
|
33
|
List.filter_map
|
34
|
(fun a ->
|
35
|
let a' = red a in
|
36
|
if is_true a' then None else Some a')
|
37
|
l
|
38
|
in
|
39
|
match l' with
|
40
|
| [] ->
|
41
|
True
|
42
|
| [ a ] ->
|
43
|
a
|
44
|
| l' when List.exists is_false l' ->
|
45
|
False
|
46
|
| _ ->
|
47
|
And l')
|
48
|
| Or l -> (
|
49
|
let l' =
|
50
|
List.filter_map
|
51
|
(fun a ->
|
52
|
let a' = red a in
|
53
|
if is_false a' then None else Some a')
|
54
|
l
|
55
|
in
|
56
|
match l' with
|
57
|
| [] ->
|
58
|
assert false
|
59
|
| [ a ] ->
|
60
|
a
|
61
|
| l' when List.exists is_true l' ->
|
62
|
True
|
63
|
| _ ->
|
64
|
Or l')
|
65
|
| Imply (a, b) ->
|
66
|
let a' = red a in
|
67
|
let b' = red b in
|
68
|
if a' = b' || is_false a' || is_true b' then True
|
69
|
else if is_true a' then b'
|
70
|
else Imply (a', b')
|
71
|
| Exists (x, p) -> (
|
72
|
let p' = red p in
|
73
|
if is_true p' then True else match x with [] -> p' | x -> Exists (x, p'))
|
74
|
| Forall (x, p) -> (
|
75
|
let p' = red p in
|
76
|
if is_true p' then True else match x with [] -> p' | x -> Forall (x, p'))
|
77
|
| Ternary (x, a, b) ->
|
78
|
let a' = red a in
|
79
|
let b' = red b in
|
80
|
Ternary (x, a', b')
|
81
|
| f ->
|
82
|
f
|
83
|
|
84
|
(* smart constructors *)
|
85
|
|
86
|
let vals vs = List.map (fun v -> Val v) vs
|
87
|
|
88
|
let mk_pred_call pred = Predicate pred
|
89
|
|
90
|
let mk_transition ?(mems = ISet.empty) ?(insts = IMap.empty) ?r ?i ?inst
|
91
|
stateless id vars =
|
92
|
let tr =
|
93
|
mk_pred_call
|
94
|
(Transition
|
95
|
( stateless,
|
96
|
id,
|
97
|
inst,
|
98
|
i,
|
99
|
vals vars,
|
100
|
(match r with Some _ -> true | None -> false),
|
101
|
mems,
|
102
|
insts ))
|
103
|
in
|
104
|
match r, inst with
|
105
|
| Some r, Some inst ->
|
106
|
ExistsMem (id, mk_pred_call (Reset (id, inst, r)), tr)
|
107
|
| _ ->
|
108
|
tr
|
109
|
|
110
|
let mk_memory_pack ?i ?inst id = mk_pred_call (MemoryPack (id, inst, i))
|
111
|
|
112
|
let mk_state_variable_pack x = StateVarPack (StateVar x)
|
113
|
|
114
|
let mk_state_assign_tr x v = Equal (Memory (StateVar x), Val v)
|
115
|
|
116
|
let mk_conditional_tr v t f = Ternary (Val v, t, f)
|
117
|
|
118
|
let mk_branch_tr x =
|
119
|
let open Lustre_types in
|
120
|
function
|
121
|
| [ (h1, spec1); (h2, spec2) ] when h1 = tag_true && h2 = tag_false ->
|
122
|
Ternary (Var x, spec1, spec2)
|
123
|
| [ (h1, spec1); (h2, spec2) ] when h1 = tag_false && h2 = tag_true ->
|
124
|
Ternary (Var x, spec2, spec1)
|
125
|
| hl ->
|
126
|
let n = List.length hl in
|
127
|
And (List.mapi (fun k (t, spec) ->
|
128
|
let tag = Tag (t, x.var_type) in
|
129
|
let x = Var x in
|
130
|
let c = if k = n - 1 then GEqual (x, tag) else Equal (x, tag) in
|
131
|
Imply (c, spec)) hl)
|
132
|
|
133
|
let mk_assign_tr x v = Equal (Var x, Val v)
|