-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstorage_cmp_impl.v
147 lines (119 loc) · 4.55 KB
/
storage_cmp_impl.v
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
Require Import Arith.
Require Import Nat.
Require Import Bool.
Require Import bbv.Word.
Require Import Coq.NArith.NArith.
Require Import List.
Import ListNotations.
Require Import FORVES2.constants.
Import Constants.
Require Import FORVES2.program.
Import Program.
Require Import FORVES2.execution_state.
Import ExecutionState.
Require Import FORVES2.stack_operation_instructions.
Import StackOpInstrs.
Require Import FORVES2.misc.
Import Misc.
Require Import FORVES2.symbolic_state.
Import SymbolicState.
Require Import FORVES2.symbolic_state_eval.
Import SymbolicStateEval.
Require Import FORVES2.valid_symbolic_state.
Import ValidSymbolicState.
Require Import FORVES2.valid_symbolic_state.
Import ValidSymbolicState.
Require Import FORVES2.symbolic_state_cmp.
Import SymbolicStateCmp.
Require Import FORVES2.eval_common.
Import EvalCommon.
Require Import FORVES2.constraints.
Import Constraints.
Require Import FORVES2.context.
Import Context.
Module StorageCmpImpl.
(* just handles the case of empty storage updates *)
Definition trivial_storage_cmp (sstack_val_cmp : sstack_val_cmp_t) (ctx: ctx_t) (sstrg1 sstrg2 :sstorage) (maxidx1: nat) (sb1: sbindings) (maxidx2: nat) (sb2: sbindings) (ops: stack_op_instr_map) : bool :=
match sstrg1,sstrg2 with
| [], [] => true
| _, _ => false
end.
(* identical storage updates *)
Fixpoint basic_storage_cmp (sstack_val_cmp : sstack_val_cmp_t) (ctx: ctx_t) (sstrg1 sstrg2 :sstorage) (maxidx1: nat) (sb1: sbindings) (maxidx2: nat) (sb2: sbindings) (ops: stack_op_instr_map) : bool :=
match sstrg1,sstrg2 with
| [], [] => true
| (U_SSTORE _ skey1 svalue1)::sstrg1', (U_SSTORE _ skey2 svalue2)::sstrg2' =>
if sstack_val_cmp ctx skey1 skey2 maxidx1 sb1 maxidx2 sb2 ops then
if sstack_val_cmp ctx svalue1 svalue2 maxidx1 sb1 maxidx2 sb2 ops then
basic_storage_cmp sstack_val_cmp ctx sstrg1' sstrg2' maxidx1 sb1 maxidx2 sb2 ops
else
false
else
false
| _, _ => false
end.
Definition swap_storage_update (ctx: ctx_t) (u1 u2 : storage_update sstack_val) (maxid: nat) (sb: sbindings) : bool :=
match u1, u2 with
| U_SSTORE _ key1 _, U_SSTORE _ key2 _ =>
match follow_in_smap key1 maxid sb with
| Some (FollowSmapVal smv1 _ _) =>
match smv1 with
| SymBasicVal sv1 =>
match follow_in_smap key2 maxid sb with
| Some (FollowSmapVal smv2 _ _) =>
match smv2 with
| SymBasicVal sv2 =>
match sv1, sv2 with
| Val v1, Val v2 => ((wordToN v2) <? (wordToN v1))%N
| _, _ => chk_lt_wrt_ctx ctx sv1 sv2
end
| _ => false
end
| _ => false
end
| _ => false
end
| _ => false
end
end.
Fixpoint reorder_updates' (d : nat) (ctx: ctx_t) (sstrg :sstorage) (maxid: nat) (sb: sbindings) : bool * sstorage :=
match d with
| O => (false,sstrg)
| S d' =>
match sstrg with
| u1::u2::sstrg' =>
if swap_storage_update ctx u1 u2 maxid sb then
match reorder_updates' d' ctx (u1::sstrg') maxid sb with
(_,sstrg'') => (true,u2::sstrg'')
end
else
match reorder_updates' d' ctx (u2::sstrg') maxid sb with
(r,sstrg'') => (r,u1::sstrg'')
end
| _ => (false,sstrg)
end
end.
(* n is basically the length of sstrg, we pass it as a parameter to
avoid computing *)
Fixpoint reorder_storage_updates (d n: nat) (ctx: ctx_t) (sstrg :sstorage) (maxid: nat) (sb: sbindings) : sstorage :=
match d with
| O => sstrg
| S d' =>
match reorder_updates' n ctx sstrg maxid sb with
| (changed,sstrg') =>
if changed then
reorder_storage_updates d' n ctx sstrg' maxid sb
else
sstrg'
end
end.
Definition po_storage_cmp (sstack_val_cmp : sstack_val_cmp_t) (ctx: ctx_t) (sstrg1 sstrg2 :sstorage) (maxidx1: nat) (sb1: sbindings) (maxidx2: nat) (sb2: sbindings) (ops: stack_op_instr_map) : bool :=
let n1 := length sstrg1 in
let n2 := length sstrg2 in
if (n1 =? n2) then
let sstrg1' := reorder_storage_updates n1 n1 ctx sstrg1 maxidx1 sb1 in
let sstrg2' := reorder_storage_updates n2 n2 ctx sstrg2 maxidx2 sb2 in
basic_storage_cmp sstack_val_cmp ctx sstrg1' sstrg2' maxidx1 sb1 maxidx2 sb2 ops
else
false.
End StorageCmpImpl.