Inductive variable := x | y.
Inductive function := plus | main | errF.
Inductive constructor := zero | succ | errC.
Scheme Equality for variable.
Scheme Equality for function.
Scheme Equality for constructor.
Module PlusSyntax <: Interface.SYNTAX.
Definition variable := variable.
Definition function := function.
Definition constructor := constructor.
Definition function_default := errF.
Definition constructor_default := errC.
Definition variable_eq_dec := variable_eq_dec.
Definition function_eq_dec := function_eq_dec.
Definition constructor_eq_dec := constructor_eq_dec.
End PlusSyntax.
Module Import Syn := Interface.MkSyn(PlusSyntax).
Definition var_coercion : variable -> term := var_coercion_gen.
Coercion var_coercion : variable >-> term.
Notation " 'Z' " := (capply zero []).
Notation " x '.+1' " := (capply succ [x:term]) (at level 60).
Definition plus_prog : list rule :=
[
main (: x, y :)    --> plus (: plus (: x, y :), plus (: x, y :) :) ;
plus (: Z, y :)    --> y ;
plus (: x.+1, y :) --> (plus (: x, y :)) .+1
].
Module PlusProg <: Syn.PROGRAM.
Definition prog := plus_prog.
End PlusProg.
Module Import Prog := Syn.MkProg (PlusProg).
Definition rank : function -> nat := ltac:(autorank function_beq ranklist).
Fixpoint quote_value (n : nat) : value :=
match n with
| 0    => c_capply zero []
| S n' => c_capply succ [quote_value n']
end.

(* Specifications: *)
(* It's a program *)
Proposition UnaryAdd_is_wf: wf_prog.
(* PPO *)
Proposition UnaryAdd_is_ppo : PPO_prog rank.
Definition cs (c : constructor) := 1. (* same for all *)
(* QI *)
Lemma qic_nonzero : constructor_non_zero cs.
Lemma qif_monotonic : monotonicity_qif qif.
Lemma qi_is_compatible : compatible_QI qic qif.
Proposition qi_is_valid : valid_QI mcs qic qif cs.
(* P-criterion *)
Theorem plus_polytime: forall i s p c f lv d v,
let t := fapply f lv in
let pi := cbv_update i s p c t d v in
cbv_wf pi -> cache_bounded qic qif c ->
cbv_size pi <= global_bound mcs qif f lv c.