(* ** Examples *)
Arguments mult : simpl never.
Arguments plus : simpl never.
(* Disable the warnings regarding [Undo]. This is a demonstration file. *)
Set Warnings "-undo-batch-mode,-non-interactive".
(* *** Copy.v *)
Definition CopyValue_sizefun {sigX X : Type} {cX : codable sigX X} (x : X) : Vector.t (nat->nat) 2 := [|id; CopyValue_size x|].
(* Same example, but using the specification language *)
(* Example using the specification language and lifting: Increment two numbers *)
Definition Incr2 : pTM sigNat^+ unit 2 :=
Constr_S@[|Fin0|];; Constr_S@[|Fin1|].
Definition Incr2_steps := 1 + Constr_S_steps + Constr_S_steps.
(* More increments *)
Definition Incr3 : pTM sigNat^+ unit 3 :=
Constr_S@[|Fin0|];; Constr_S@[|Fin1|];; IncrementTwice@[|Fin2|].
Definition Incr3_steps := 2 + Constr_S_steps + Constr_S_steps + IncrementTwice_steps.
(* *** Addition *)
Definition Add_Step : pTM sigNat^+ (option unit) 2 :=
If (CaseNat @ [|Fin1|])
(Return (Constr_S @ [|Fin0|]) None)
(Return Nop (Some tt)).
(* Definition Add_Step_Rel : pRel sigNat^+ (option unit) 2 := fun tin '(yout, tout) => forall a b sa sb, tin [@Fin0] ≃(;sa) a -> tin [@Fin1] ≃(;sb) b -> match yout, b with | Some tt, O => (* break *)
tout[@Fin0] ≃(;sa) a /\
tout[@Fin1] ≃(;sb) b
| None, S b' =>
tout[@Fin0] ≃(;pred sa) S a /\
tout[@Fin1] ≃(;S sb) b'
| _, _ => False
end.
*)
Definition Add_Step_Post : nat*nat -> option unit -> Assert sigNat^+ 2 :=
fun '(a,b) =>
(fun yout =>
≃≃(([yout = if b then Some tt else None]
,[|Contains _ (match b with 0 => a | _ => S a end);Contains _ (pred b)|]))).
Definition Add_Loop : pTM sigNat^+ unit 2 := While Add_Step.
(* Definition Add_Loop_Rel : pRel sigNat^+ unit 2 := ignoreParam ( fun tin tout => forall a b sa sb, tin [@Fin0] ≃(;sa) a -> tin [@Fin1] ≃(;sb) b -> tout[@Fin0] ≃(;sa-b) b + a /\ tout[@Fin1] ≃(;sb+b) 0 ). *)
(* The same with termination! *)
Definition Add_Step_steps : nat := 9.
(* With space *)
Definition Add_Step_size (a b : nat) : Vector.t (nat->nat) 2 :=
match b with
| 0 => [|id; id|]
| S b' => [|S; S|]
end.
Definition Add_Loop_steps b := 9 + 10 * b.
Fixpoint Add_Loop_size (a b : nat) : Vector.t (nat->nat) 2 :=
match b with
| O => Add_Step_size a b
| S b' => Add_Step_size a b >>> Add_Loop_size (S a) b'
end.

Lemma Add_Loop_SpecT_size (a b : nat) (ss : Vector.t nat 2) :
TripleT
(≃≃([],  withSpace ( [|Contains _ a; Contains _ b|]) ss))
(Add_Loop_steps b)
(Add_Loop)
(fun _ => tspec
([], withSpace [|Contains _ (a+b); Contains _ 0|]
(appSize (Add_Loop_size a b) ss))).