Require Import Arith Lia List.
From Undecidability.HOU Require Import std.std calculus.prelim.
Import ListNotations.

Inductive deq :=
| Con (x: )
| Add (x y z: )
| Mul (x y z: ).

Notation "x =ₑ 1" := (Con x) (at level 66).
Notation "x +ₑ y =ₑ z" := (Add x y z) (at level 66, y at next level).
Notation "x *ₑ y =ₑ z" := (Mul x y z) (at level 66, y at next level).
Reserved Notation "sigma ⊢ₑ e" (at level 60, e at level 99).

Inductive sol (sigma: ) : deq Prop :=
| solC x: x = 1 ⊢ₑ x =ₑ 1
| solA x y z: x + y = z ⊢ₑ x +ₑ y =ₑ z
| solM x y z: x * y = z ⊢ₑ x *ₑ y =ₑ z
where "sigma ⊢ₑ e" := (sol e).

Definition Sol (sigma: ) (E: list deq) := e, e E ⊢ₑ e.
Notation "sigma ⊢⁺ₑ E" := (Sol E) (at level 60, E at level 99).
Definition (E: list deq) := sigma, E.

Definition vars__de (e: deq) :=
  match e with
  | x =ₑ 1 [x]
  | x +ₑ y =ₑ z [x; y; z]
  | x *ₑ y =ₑ z [x; y; z]
  end.

Definition Vars__de E :=
  nodup Nat.eq_dec (flat_map vars__de E).

Lemma Vars__de_in e E:
  e E y, y vars__de e y Vars__de E.
Proof.
  unfold Vars__de; intros; eapply nodup_In, in_flat_map.
  exists e. intuition.
Qed.