Section ListFacts.
Definition sat φ l := Forall (h10uc_sem φ) l.
(* needs 2 fresh variables *)
(* x is 0 if 1 + x + x * x = y and 1 + x + y * y = z and 1 + y + x * x = z *)
Definition express_0 (x: nat) (f: nat -> nat) := [(x, x, f 0); (x, f 0, f 1); (f 0, x, f 1)].
Definition express_0f := [1; 2].
(* needs 2 fresh variables *)
(* x is 1 if 1 + y + y * y = x and 1 + y + x * x = z and 1 + x + y * y = z *)
Definition express_1 (x: nat) (f: nat -> nat) := [(f 0, f 0, x); (f 0, x, f 1); (x, f 0, f 1)].
Definition express_1f := [0; 2].
(* needs 3 fresh variables *)
(* x is 1 + y if 1 + y + 0 * 0 = x *)
Definition express_succ (x y: nat) (f: nat -> nat) := (express_0 (f 2) f) ++ [(y, f 2, x)].
Definition express_succf := express_0f ++ [0].
(* needs 7 fresh variables *)
(* x = y * y if 1 + 0 + y * y = 1 + x *)
Definition express_square (x y: nat) (f: nat -> nat) :=
(express_0 (f 5) f) ++ (express_succ (f 6) x (fun i => f (2+i))) ++ [(f 5, y, f 6)].
Definition express_squaref φx :=
express_0f ++ express_succf ++ [0; 1 + φx].

Lemma express_squareE x y f φ: sat φ (express_square x y f) -> φ x = (φ y) * (φ y).