Section ra_dio_poly_eval.
Variable (v : vec nat (n+m)).
Notation φ := (fun i => vec_pos v (pos_left _ i)).
Notation ν := (fun i => vec_pos v (pos_right _ i)).
Fact ra_dio_poly_val p : ⟦ra_dio_poly p⟧ v (dp_eval φ ν p).
Variable (p q : dio_polynomial (pos n) (pos m)).
Definition ra_dio_poly_eq : recalg (n+m).
Fact ra_dio_poly_eq_val : { e | ⟦ra_dio_poly_eq⟧ v e /\ (e = 0 <-> dp_eval φ ν p = dp_eval φ ν q) }.
Opaque ra_dio_poly_eq.
Hint Resolve ra_dio_poly_eq_prim : core.
Definition ra_dio_poly_test : recalg (S m).
Fact ra_dio_poly_test_total : total ⟦ra_dio_poly_test⟧.
Fact ra_dio_poly_test_rel v e : ⟦ra_dio_poly_test p q⟧ v e
-> e = 0 <-> dp_eval (φ (vec_head v) (vec_tail v))
(ν (vec_head v) (vec_tail v)) p
= dp_eval (φ (vec_head v) (vec_tail v))
(ν (vec_head v) (vec_tail v)) q.
Opaque ra_dio_poly_test.
Definition ra_dio_poly_find : recalg m.
(* ra_dio_poly_find terminates on w iff some solution of p(w,x1,...,xn) = q(w,x1,...,xn) exists  so termination of ra_dio_poly_find terminates on w simulates the existence of a solution to a given diophantine equation *)

Theorem ra_dio_poly_find_spec w :  ex (⟦ra_dio_poly_find⟧ w)
<-> exists v, dp_eval (vec_pos v) (vec_pos w) p
= dp_eval (vec_pos v) (vec_pos w) q.