Section diophantine_system.
(* v : cst = nat      constant (natural number) p q : par = nat    parameter x y z : var = nat  existentially quantified variable  equations are of 4 types 1) x = v 2) x = p 3) x = y + z 4) x = y * z  We represent a relation between parameters R by a list of equations l and one variable s : var such that a) for any value f : nat -> nat of the params, l[f] has a solution b) for any value f : nat -> nat of the params,  R f <-> ((s=0)::l)[f] has a solution  How do we simulate x = n ?  x = n <-> s = 0 /\ exists p q u v w, s = p+q /\ u = p+v /\ u = q+w /\ v = x /\ w = n  How do we simulate x = y + z  x = y+z <-> s = 0 /\ exists p q u v w r t, s = p+q /\ t = p+u /\ t=q+r /\ r = v+w /\ u = x /\ v = y /\ w = z  We implement conjunction (cap), disjunction (cup) and exists so that we get a linear encoding  cap) R by (lR,xR) and S by (lS,xS) we assume (lR,xR) and (lS,xS) do not share existential variables (always possible by renaming those of S)  R cap S = (lR U lS U { z = x+y },z) where z is fresh  cup) R cup S = (lR U lS U { z = x*y },z)  exists) ∃n.R f{p<-n} = (lR[p<-0], ...)  *)
Inductive dio_elem_expr : Set :=
| dee_nat  : nat -> dio_elem_expr   (* c : constant *)
| dee_var  : nat -> dio_elem_expr   (* v : existentially quant. var *)
| dee_par  : nat -> dio_elem_expr   (* p : parameter *)
| dee_comp : dio_op -> nat -> nat -> dio_elem_expr. (* v1 op v2 *)
Notation dee_add := (dee_comp do_add).
Notation dee_mul := (dee_comp do_mul).
Definition dee_eval φ ν e :=
match e with
| dee_nat n => n
| dee_var v => φ v
| dee_par i => ν i
| dee_comp o v w => de_op_sem o (φ v) (φ w)
end.
Definition dee_vars e x  :=
match e with
| dee_nat _ => False
| dee_var v => x = v
| dee_par _ => False
| dee_comp _ v w => x = v \/ x = w
end.
Fact dee_eval_ext e φ1 ν1 φ2 ν2  :
(forall x, dee_vars e x -> φ1 x = φ2 x)
-> (forall x, ν1 x = ν2 x)
-> dee_eval φ1 ν1 e = dee_eval φ2 ν2 e.
Definition dc_dec k c := (fst c, dee_dec k (snd c)).
Fact dc_eval_dec φ ν k c : dc_eval φ ν (dc_dec k c) <-> dc_eval φ  (fun x => match x with 0 => φ k | S x => ν x end) c.
(* x = i <~~> s = 0 /\ exists p q u v w, s = p+q /\ u = p+v /\ u = q+w /\ v = x /\ w = i *)

Lemma dio_repr_at_cst x i a : dio_repr_at (fun ν => ν x = i) a 6 5.