Section Transport.
Variable φ : nat -> nat. (* solution of h10cs *)
Variable Hφ : forall c, In c h10cs -> h10c_sem c φ.
Fixpoint value_bound (cs: list h10c) : nat :=
match cs with
| [] => 0
| (h10c_one x) :: cs => 1 + φ x + value_bound cs
| (h10c_plus x y z) :: cs => 1 + φ x + φ y + φ z + value_bound cs
| (h10c_mult x y z) :: cs => 1 + φ x + φ y + φ z + value_bound cs
end.
(* number encoding *)
Definition poly_num n := poly_var (n+zt).
Definition GammaU n := map (fun i => Ut (poly_num i)) (seq 0 (1+n)).
Definition GammaS0 n := map (fun i => St (poly_num i, poly_num 0, poly_num i)) (seq 0 (1+n)).
Definition GammaS1 n := map (fun i => St (poly_num i, poly_num 1, poly_num (1+i))) (seq 0 n).
Definition GammaP0 n := map (fun i => Pt (poly_num i, poly_num 0, poly_num 0)) (seq 0 (1+n)).
Definition GammaUSP n := locked (GammaU (S n) ++ (GammaS0 (S n) ++ GammaS1 (S n)) ++ GammaP0 (S n)).
Definition h10cφ_poly_type (c: h10c) : poly_type :=
match c with
| (h10c_one x) => St (poly_num (φ x), poly_num 0, poly_num 1)
| (h10c_plus x y z) => St (poly_num (φ x), poly_num (φ y), poly_num (φ z))
| (h10c_mult x y z) => Pt (poly_num (φ x), poly_num (φ y), poly_num (φ z))
end.
Definition Gammaφ := map h10cφ_poly_type h10cs.
Fact GammaUSn {n} : GammaU (S n) = GammaU n ++ [Ut (poly_num (1+n))].

Lemma introduce_Pts (n n1 n2: nat) (Gamma: environment):
n1 <= S n -> n2 <= S n -> n1 * n2 <= S n ->
iipc2 (locked Gamma0 ++ GammaUSP n ++ (Pt (poly_num n1, poly_num n2, poly_num (n1*n2)) :: Gamma)) (poly_var tt) ->
iipc2 (locked Gamma0 ++ GammaUSP n ++ Gamma) (poly_var tt).