forked from AU-COBRA/ConCert
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CounterCertifiedExtraction.v
168 lines (133 loc) · 5.43 KB
/
CounterCertifiedExtraction.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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
(** * Extraction of a simple counter contract *)
From MetaCoq.Template Require Import All.
From ConCert.Embedding Require Import Notations.
From ConCert.Embedding.Extraction Require Import PreludeExt.
From ConCert.Extraction Require Import LPretty.
From ConCert.Extraction Require Import LiquidityExtract.
From ConCert.Extraction Require Import Common.
From ConCert.Utils Require Import Automation.
From ConCert.Execution Require Import Serializable.
From ConCert.Execution Require Import Blockchain.
From Coq Require Import String.
From Coq Require Import Lia.
From Coq Require Import ZArith.
Import MonadNotation.
Local Open Scope string_scope.
Open Scope Z.
Definition PREFIX := "".
Module Counter.
(** Enabling recursors for records allows for deriving [Serializable] instances. *)
Set Nonrecursive Elimination Schemes.
(** The definitions in this section are generalized over the [ChainBase] that specifies the type of addresses and which properties such a type must have *)
Notation address := nat.
Definition operation := ActionBody.
Definition storage := Z × address.
Definition init (ctx : SimpleCallCtx) (setup : Z * address) : option storage :=
let ctx' := ctx in (* prevents optimisations from removing unused [ctx] *)
Some setup.
Inductive msg :=
| Inc (_ : Z)
| Dec (_ : Z).
Definition inc_balance (st : storage) (new_balance : Z) :=
(st.1 + new_balance, st.2).
Definition dec_balance (st : storage) (new_balance : Z) :=
(st.1 - new_balance, st.2).
Definition counter (msg : msg) (st : storage)
: option (list operation * storage) :=
match msg with
| Inc i =>
if (0 <=? i) then
Some ([],inc_balance st i)
else None
| Dec i =>
if (0 <=? i) then
Some ([],dec_balance st i)
else None
end.
Definition COUNTER_MODULE : LiquidityMod msg _ (Z × address) storage operation :=
{| (* a name for the definition with the extracted code *)
lmd_module_name := "liquidity_counter" ;
(* definitions of operations on pairs and ints *)
lmd_prelude := prod_ops ++ nl ++ int_ops;
(* initial storage *)
lmd_init := init ;
(* no extra operations in [init] are required *)
lmd_init_prelude := "" ;
(* the main functionality *)
lmd_receive := counter ;
(* code for the entry point *)
lmd_entry_point := printWrapper (PREFIX ++ "counter") ++ nl
++ printMain |}.
(** These definitions define a contract in a format required by the execution framework. Note that these definitions will not be used for extraction. We extract the definitions above instead. *)
Definition counter_init (ch : Chain) (ctx : ContractCallContext) :=
init_wrapper init ch ctx.
Definition counter_receive (chain : Chain) (ctx : ContractCallContext)
(st : storage) (msg : option msg) : option (storage * list ActionBody)
:= match msg with
| Some m => match counter m st with
| Some res => Some (res.2,res.1)
| None => None
end
| None => None
end.
(** Deriving the [Serializable] instances for the state and for the messages *)
Global Instance Msg_serializable : Serializable msg :=
Derive Serializable msg_rect<Inc, Dec>.
(** A contract instance used by the execution framework *)
Definition CounterContract :=
build_contract counter_init counter_receive.
End Counter.
Import Counter.
Lemma inc_correct state n m :
0 <= m ->
state.1 = n ->
exists new_state, counter (Inc m) state = Some ([],new_state)
/\ new_state.1 = (n + m)%Z.
Proof.
intros Hm Hn.
eexists. split.
- simpl. destruct ?; propify;auto;lia.
- simpl. congruence.
Qed.
Lemma dec_correct state n m :
0 <= m ->
state.1 = n ->
exists new_state, counter (Dec m) state = Some ([],new_state)
/\ new_state.1 = (n - m)%Z.
Proof.
intros Hm Hn.
eexists. split.
- simpl. destruct ?; propify;auto;lia.
- simpl. congruence.
Qed.
(** A translation table for definitions we want to remap. The corresponding top-level definitions will be *ignored* *)
Definition TT_remap : list (kername * string) :=
[ remap <%% bool %%> "bool"
; remap <%% list %%> "list"
; remap <%% Amount %%> "tez"
; remap <%% address_coq %%> "address"
; remap <%% time_coq %%> "timestamp"
; remap <%% option %%> "option"
; remap <%% Z.add %%> "addInt"
; remap <%% Z.sub %%> "subInt"
; remap <%% Z.leb %%> "leInt"
; remap <%% Z %%> "int"
; remap <%% nat %%> "key_hash" (* type of account addresses*)
; remap <%% operation %%> "operation"
; remap <%% @fst %%> "fst"
; remap <%% @snd %%> "snd" ].
(** A translation table of constructors and some constants. The corresponding definitions will be extracted and renamed. *)
Definition TT_rename :=
[ ("Some", "Some")
; ("None", "None")
; ("Z0" ,"0")
; ("nil", "[]") ].
(** We run the extraction procedure inside the [TemplateMonad].
It uses the certified erasure from [MetaCoq] and the certified deboxing procedure
that removes application of boxes to constants and constructors. *)
Time MetaCoq Run
(t <- liquidity_extraction PREFIX TT_remap TT_rename [] COUNTER_MODULE ;;
tmDefinition COUNTER_MODULE.(lmd_module_name) t).
Print liquidity_counter.
(** We redirect the extraction result for later processing and compiling with the Liquidity compiler *)
Redirect "../extraction/tests/extracted-code/liquidity-extract/CounterCertifiedExtraction.liq" Compute liquidity_counter.