generation
module.
They tell us how to compose
abstract machine code to build
code for Call_M
, Call_C
and Call_K
calls (see the module spec )
We prove 7 lemmas, which all have the same form:
(...)(gencode call1)-> (gencode call2)-> ... (gencode call). Proof. Realizer [...][c1,c2,...:Code]c. ... Qed.where call1,... are terms of type
Call
,
and c is a Fw-term of type Code
.
Call_M
M3:(gencode (Call_M three))
(Call_M three)
: it is a constructive proof (realized
by the code (seq PUSH (seq SQR (seq MUL End)))
)
M2q:(q:nat)(gencode (Call_M (two_power q)))
(Call_M (two_power p))
is obtained
by a sequence of p SQR
s.
So the proof begins with:
Realizer [p:nat]<Code>Match p with End ([_,c:?](seq SQR c)) end.
C2M:(p,q:nat)(gencode (Call_C p q ))-> (gencode (Call_M p)).
(Call_M p q)
is stronger
than the specification of (Call_M p)
. So this lemma
is realized by identity on Code
:
Realizer [p,q:nat][c:Code]c.
Call_C
MMC:(p,q:nat)(gencode (Call_M p))-> (gencode (Call_M q))-> (gencode (Call_C (mult q p) p)).
Therefore, the proof begins with:
Realizer [p,q:nat][c,c':Code](app c c'). Program_all.
KMC:(p,q,r:nat)(gencode (Call_K p r))-> (gencode (Call_M q))-> (gencode (Call_C (plus (mult q p) r) p)).
KMC
is realized by:
Realizer [p,q,r:nat][cpr,cq:Code] (app cpr (app cq (seq MUL End))). ...
Call_K
MMK: (p,q:nat)(gencode (Call_M p))-> (gencode (Call_M q))-> (gencode (Call_K (mult q p) p)).
Realizer [p,q:nat][cp,cq:Code](app cp (seq PUSH cq)).
KMK:(p,q,r:nat) (gencode (Call_K p r))-> (gencode (Call_M q))-> (gencode (Call_K (plus (mult q p) r) p)).
Realizer [p,q,r:nat][kpr,mq:Code] (app kpr (seq PUSH (seq SWAP(app mq (seq MUL End))))).
Realizer
andProgram
, and have to solve some
logical goals. These goals are solved using some properties of the
monoid ; the lemma Exec_app
of the
module machine
is used to prove the correction of code obtained by appending.
Please notice the repeated use of Inversion_clear
s, where
s is an hypothesis of the form (Spec <some_call>
c0)
, where <some_call> is a term of type
Call
and c0
a variable of type Code
.
For instance, in the proof of KMC
, we have the context:
p : nat q : nat c : (gencode (Call_M p)) c0 : Code s : (Spec (Call_M p) c0) c' : (gencode (Call_M q)) c'0 : Code s0 : (Spec (Call_M q) c'0) a : M s1 : Stack ============================ (Exec c'0 (Exec c0 (config a s1)))= (config (power a (mult q p)) s1)the command "
Inversion_clear s.
" adds to the context the hypothesis
H: (a:M)(s:Stack)(Exec c0 (config a s))= (config (power a p) s)which reflects the intended semantics of
(Call_M p)
(see the
module
spec
), and is used
as "Rewrite H.
"; load "Demo.ml";; #open "Demo";;The lemmas
M3
,M2q
, MMC
, ... have
their ml
translations:
#M3;; - : Code = seq (PUSH, seq (SQR, seq (MUL, End))) #M2q 6;; - : Code = seq (SQR,seq(SQR,seq(SQR,seq(SQR,seq(SQR,seq(SQR,End)))))) #KMC 10 8 7 (code_gen (dicho log2_impl) (Call_K(10, 7))) (code_gen (dicho log2_impl) (Call_M 8)) = (code_gen (dicho log2_impl) (Call_M 87));; - : builtin__bool = builtin__true
Caml
source for, say, KMC
:
let KMC p q r cpr cq = app cpr (app cq (seq(MUL,End)));;we notice that the integer parameters
p
, q
, and r
are useless in the body of the definition.
This is perfectly normal: p
, q
, and r
are
of type nat(int)
which is of type Set
, and are
not removed by extraction, but they are used only for logical purpose, and
their use in removed by the extraction algorithm.