(*s Simplified formulae: *)
Inductive CGSForm : Set :=
  | CGSleq : ad -> ad -> D -> CGSForm
  | CGSand : CGSForm -> CGSForm -> CGSForm
  | CGSor : CGSForm -> CGSForm -> CGSForm.(*s Simplified formulae: *)
Inductive CGSForm : Set :=
  | CGSleq : ad -> ad -> D -> CGSForm
  | CGSand : CGSForm -> CGSForm -> CGSForm
  | CGSor : CGSForm -> CGSForm -> CGSForm.(*s Simplified formulae: *)
Inductive CGSForm : Set :=
  | CGSleq : ad -> ad -> D -> CGSForm
  | CGSand : CGSForm -> CGSForm -> CGSForm
  | CGSor : CGSForm -> CGSForm -> CGSForm.(*s Simplified formulae: *)
Inductive CGSForm : Set :=
  | CGSleq : ad -> ad -> D -> CGSForm
  | CGSand : CGSForm -> CGSForm -> CGSForm
  | CGSor : CGSForm -> CGSForm -> CGSForm.Fixpoint CG_of_CGS (fs : CGSForm) : CGForm :=
  match fs with
  | CGSleq x y d => CGleq x y d
  | CGSand fs0 fs1 => CGand (CG_of_CGS fs0) (CG_of_CGS fs1)
  | CGSor fs0 fs1 => CGor (CG_of_CGS fs0) (CG_of_CGS fs1)
  end.Definition CGSeval (rho : ad -> D) (fs : CGSForm) :=
  CGeval rho (CG_of_CGS fs).(*s Is $x\leq y+d$ consistent with [cg]? *)

Definition CG_test_ineq (cg : CGraph1) (n : nat) (x y : ad) 
  (d : D) := Ddle (Some (Dneg d)) (ad_1_path_dist_1 cg y x (M0 unit) n).(*s Invariants: [cg] is consistent, [|cg|<=n].
       [(CGS_solve_1 cg n fsl gas)]
       returns [true] iff [cg /\ fsl /\ anchor=anchor_value] is consistent,
       	 where [fsl] is understood as the conjunction of all the [fs] in [fsl];
         i.e. iff [cg /\ fsl] alone is consistent 
          (lemmas [CG_anchored_then_consistent] and [CG_consistent_then_anchored)].
       [gas] is intended to be [>=] the sum of sizes of all formulas in [fsl]. *)

Fixpoint CGS_solve_1 (cg : CGraph1) (n : nat) (fsl : list CGSForm)
 (gas : nat) {struct gas} : bool :=
  match gas with
  | O => def_answer
  | S gas' =>
      match fsl with
      | nil => true
      | fs :: fsl' =>
          match fs with
          | CGSleq x y d =>
              if CG_test_ineq cg n x y d
              then
               let cg' := CG_add cg x y d in CGS_solve_1 cg' (S n) fsl' gas'
              else false
          | CGSand fs0 fs1 => CGS_solve_1 cg n (fs0 :: fs1 :: fsl') gas'
          | CGSor fs0 fs1 =>
              if CGS_solve_1 cg n (fs0 :: fsl') gas'
              then true
              else CGS_solve_1 cg n (fs1 :: fsl') gas'
          end
      end
  end.(*s Size of a set of formula and of a list of formula *)

Fixpoint FSize (f : CGSForm) : nat :=
  match f with
  | CGSand f0 f1 => S (FSize f0 + FSize f1)
  | CGSor f0 f1 => S (FSize f0 + FSize f1)
  | _ => 1
  end.Fixpoint FlSize (fsl : list CGSForm) : nat :=
  match fsl with
  | nil => 0
  | fs :: fsl' => FSize fs + FlSize fsl'
  end.Definition CGS_solve (fs : CGSForm) :=
  CGS_solve_1 (M0 _) 0 (fs :: nil) (S (FSize fs)).(*s Interpretation of a list of formula as a conjonction *)

Fixpoint CGSeval_l (rho : ad -> D) (fsl : list CGSForm) {struct fsl} :
 Prop :=
  match fsl with
  | nil => True
  | fs :: fsl' => CGSeval rho fs /\ CGSeval_l rho fsl'
  end.

(* Specifications: *)
Lemma FSize_geq_1 : forall fs : CGSForm, {n : nat | FSize fs = S n}.
Lemma FlSize_is_O : forall fsl : list CGSForm, FlSize fsl = 0 -> fsl = nil.
Lemma CG_add_card_le : forall (cg : CGraph1) (x y : ad) (d : D) (n : nat), MapCard _ cg <= n -> MapCard _ (CG_add cg x y d) <= S n.
Lemma CGS_solve_1_correct : forall (gas : nat) (fsl : list CGSForm) (cg : CGraph1) (n : nat), CGconsistent cg -> MapCard _ cg <= n -> FlSize fsl < gas -> CGS_solve_1 cg n fsl gas = true -> {rho : ad -> D | CGSeval_l rho fsl /\ CGsat cg rho}.
Lemma CGS_solve_correct : forall fs : CGSForm, CGS_solve fs = true -> {rho : ad -> D | CGSeval rho fs}.
Lemma CGS_translate_l : forall (fs : CGSForm) (rho : ad -> D) (d : D), CGSeval rho fs -> CGSeval (fun a : ad => Dplus d (rho a)) fs.
Lemma CGS_solve_correct_anchored : forall fs : CGSForm, CGS_solve fs = true -> {rho : ad -> D | CGSeval rho fs /\ rho anchor = anchor_value}.
Lemma CGS_solve_complete_1 : forall (gas : nat) (fsl : list CGSForm) (cg : CGraph1) (n : nat), FlSize fsl < gas -> MapCard _ cg <= n -> forall rho : ad -> D, CGsat cg rho -> CGSeval_l rho fsl -> CGS_solve_1 cg n fsl gas = true.
Lemma CGS_solve_complete : forall (fs : CGSForm) (rho : ad -> D), CGSeval rho fs -> CGS_solve fs = true.