Require Import Crypto.Specific.Framework.RawCurveParameters.
Require Import Crypto.Util.LetIn.

(***
Modulus : 2^150 - 5
Base: 32
***)

Definition curve : CurveParameters :=
  {|
    sz := 5%nat;
    base := 32;
    bitwidth := 32;
    s := 2^150;
    c := [(1, 5)];
    carry_chains := None;

    a24 := None;
    coef_div_modulus := None;

    goldilocks := None;
    karatsuba := None;
    montgomery := true;
    freeze := Some false;
    ladderstep := false;

    mul_code := None;

    square_code := None;

    upper_bound_of_exponent_loose := None;
    upper_bound_of_exponent_tight := None;
    allowable_bit_widths := None;
    freeze_extra_allowable_bit_widths := None;
    modinv_fuel := None
  |}.

Ltac extra_prove_mul_eq _ := idtac.
Ltac extra_prove_square_eq _ := idtac.


Require Import VST.msl.Extensionality.
Require Import VST.msl.sepalg.
Require Import VST.msl.ageable.
Require Import VST.msl.age_sepalg.
Require Import VST.msl.base.
Require Import VST.msl.predicates_hered.
Require Import VST.msl.predicates_sl.
Require Import VST.msl.subtypes.
Require Import VST.msl.subtypes_sl.
Require Import VST.msl.predicates_rec.

(* Given a separation algebra on type [A], we can make a separation logic
   with predicates of type  [pred A].  But the type   [B -> pred A] is also
   a natural separation logic.  These typeclasses automagically extend
   the separation-logic operators to the pointwise-function case.
   At present, this is just the beginnings of an experiment with this idea;
   don't expect it to work well enough to be useful.
   Andrew Appel, August 2012, following an approach suggested by Rob Dockins
*)

Class StarOp A := {  starOp : A -> A -> A }.

#[global] Instance baseStarOp {A}{agA: ageable A}{JA: Join A}{PA: Perm_alg A}{SA: Sep_alg A}{AgeA: Age_alg A}{EO: Ext_ord A}{EA: Ext_alg A}
 : StarOp (pred A) := {| starOp := sepcon |}.

#[global] Instance funStarOp (B: Type)(A: Type)(StarA: StarOp A) : StarOp (B -> A) :=
   {| starOp := fun (P Q : B -> A) (b : B) =>  starOp (P b) (Q b) |}.

Set Warnings "-notation-overridden".
Notation "P '*' Q" := (starOp P Q) : pred.
Set Warnings "notation-overridden".
(* Opaque baseStarOp *)

Class DerivesOp A := {  derivesOp : A -> A -> Prop }.

#[global] Instance baseDerivesOp {A}{agA: ageable A}{EO: Ext_ord A}
 : DerivesOp (pred A) := {| derivesOp := @derives A agA EO|}.

#[global] Instance funDerivesOp (B: Type)(A: Type)(DerivesA: DerivesOp A) : DerivesOp (B -> A)
 := {| derivesOp := fun (P Q : B -> A)  => forall b, derivesOp (P b) (Q b) |}.
Set Warnings "-notation-overridden".
Declare Scope logic_derives.
Notation "P '|--' Q" := (derivesOp P%pred Q%pred) : logic_derives.
Set Warnings "notation-overridden".
Open Scope logic_derives.
(* Opaque baseDerivesOp. *)

Class WandOp A := {  wandOp : A -> A -> A }.

#[global] Instance baseWandOp {A}{agA: ageable A}{JA: Join A}{PA: Perm_alg A}{SA: Sep_alg A}{AgeA: Age_alg A}{EO: Ext_ord A}{EA: Ext_alg A}
 : WandOp (pred A) := {| wandOp := wand |}.

#[global] Instance funWandOp (B: Type)(A: Type)(WandA: WandOp A) : WandOp (B -> A) :=
   {| wandOp := fun (P Q : B -> A) (b : B) =>  wandOp (P b) (Q b) |}.

Set Warnings "-notation-overridden".
Notation "P '-*' Q" := (wandOp P Q) : pred.
Set Warnings "notation-overridden".
(* Opaque baseWandOp *)

Class EmpOp A := { Emp: A}.

#[global] Instance baseEmpOp {A}{agA: ageable A}{JA: Join A}{PA: Perm_alg A}{SA: Sep_alg A}{AgeA: Age_alg A}{EO: Ext_ord A}
  : EmpOp (pred A) := {| Emp := @emp A JA SA agA AgeA EO |}.

#[global] Instance funEmpOp  (B: Type)(A: Type)(EmpA: EmpOp A) : EmpOp (B -> A) :=
   {| Emp := fun (b : B) =>  Emp  |}.

Section Test.
Variable environ: Type.
Variables (rmap : Type)
      (Join_rmap: Join rmap) (Perm_rmap: @Perm_alg rmap Join_rmap)
      (Sep_rmap: @Sep_alg rmap Join_rmap)
      (Canc_rmap: @Canc_alg rmap Join_rmap)
      (Disj_rmap: @Disj_alg rmap Join_rmap)
      (ag_rmap: ageable rmap)
      (Age_rmap: @Age_alg rmap Join_rmap ag_rmap Sep_rmap)
      (Ext_rmap: @Ext_ord rmap ag_rmap)
      (ExtA_rmap: @Ext_alg rmap ag_rmap Ext_rmap Join_rmap Sep_rmap).
#[local] Existing Instance  Join_rmap.
#[local] Existing Instance  Perm_rmap.
#[local] Existing Instance  Sep_rmap.
#[local] Existing Instance  Canc_rmap.
#[local] Existing Instance  Disj_rmap.
#[local] Existing Instance  ag_rmap.
#[local] Existing Instance  Age_rmap.
#[local] Existing Instance  Ext_rmap.
#[local] Existing Instance  ExtA_rmap.

Lemma test1: forall (P : environ -> pred rmap) (Q: pred rmap),
   P * Emp |-- P.
Proof.
 intros.
  intro. simpl; rewrite sepcon_emp.
auto.
Qed.

End Test.


Inductive Maybe a : Set
  := Nothing : Maybe a
   | Just a : Maybe a.


From Test Require Import tactic.

Section FOFProblem.

Variable Universe : Set.
Variable UniverseElement : Universe.

Variable wd_ : Universe -> Universe -> Prop.
Variable col_ : Universe -> Universe -> Universe -> Prop.

Variable col_swap1_1 : (forall A B C : Universe, (col_ A B C -> col_ B A C)).
Variable col_swap2_2 : (forall A B C : Universe, (col_ A B C -> col_ B C A)).
Variable col_triv_3 : (forall A B : Universe, col_ A B B).
Variable wd_swap_4 : (forall A B : Universe, (wd_ A B -> wd_ B A)).
Variable col_trans_5 : (forall P Q A B C : Universe, ((wd_ P Q /\ (col_ P Q A /\ (col_ P Q B /\ col_ P Q C))) -> col_ A B C)).

Theorem pipo_6 : (forall A B C D P : Universe, ((wd_ A D /\ (wd_ A B /\ (wd_ B C /\ (wd_ A C /\ (wd_ A D /\ (wd_ C D /\ (wd_ B D /\ (wd_ P A /\ (wd_ P D /\ (wd_ B P /\ (wd_ P C /\ (col_ C P D /\ (col_ A D D /\ col_ B P C))))))))))))) -> col_ B C D)).
Proof.
  time tac.
Qed.

End FOFProblem.


Require Import Coq.Lists.List.
Require Import Rewriter.Language.Pre.
Require Import Rewriter.Util.Bool.
Require Import Rewriter.Util.NatUtil.
Require Import Rewriter.Util.ListUtil.
Require Import Rewriter.Util.Prod.
Require Import Rewriter.Util.Option.
Import ListNotations.

Import Pre.RewriteRuleNotations.

Lemma eval_nat_rect_arrow
  : forall A B O_case S_case n v,
    @nat_rect_arrow_nodep A B O_case S_case ('n) v
    = ident.eagerly (@nat_rect_arrow_nodep) _ _ O_case S_case ('n) v.
Proof. reflexivity. Qed.

Lemma eval_nat_rect
  : forall P O_case S_case n,
    @Thunked.nat_rect P O_case S_case ('n)
    = ident.eagerly (@Thunked.nat_rect) _ O_case S_case ('n).
Proof. reflexivity. Qed.

Lemma eval_list_rect_arrow
  : forall A P Q N C ls v,
    @list_rect_arrow_nodep A P Q N C ls v
    = ident.eagerly (@list_rect_arrow_nodep) A P Q N C ls v.
Proof. reflexivity. Qed.

Lemma eval_list_rect
  : forall A P N C ls,
    @Thunked.list_rect A P N C ls
    = ident.eagerly (@Thunked.list_rect) A P N C ls.
Proof. reflexivity. Qed.

Lemma eval_list_case_nil
  : forall A P N C, @Thunked.list_case A P N C nil = N tt.
Proof. reflexivity. Qed.
Lemma eval_list_case_cons
  : forall A P N C x xs, @Thunked.list_case A P N C (x :: xs) = C x xs.
Proof. reflexivity. Qed.

Lemma eval_list_nth_default
  : forall A default ls n,
    @List.nth_default A default ls ('n)
    = ident.eagerly (@List.nth_default) A default ls ('n).
Proof. reflexivity. Qed.

Lemma eval_prod_rect
  : forall A B P f x y, @prod_rect_nodep A B P f (x, y) = f x y.
Proof. reflexivity. Qed.

Lemma eval_option_rect_Some
  : forall A P S N x, @Thunked.option_rect A P S N (Some x) = S x.
Proof. reflexivity. Qed.
Lemma eval_option_rect_None
  : forall A P S N, @Thunked.option_rect A P S N None = N tt.
Proof. reflexivity. Qed.

Lemma eval_bool_rect_true : forall T t f, @Thunked.bool_rect T t f true = t tt.
Proof. reflexivity. Qed.
Lemma eval_bool_rect_false : forall T t f, @Thunked.bool_rect T t f false = f tt.
Proof. reflexivity. Qed.

Import PrimitiveProd.
Import Pre.RewriteRuleNotations.

Module Export Instances.
  Global Instance eval_rect_nat_rules : rules_proofs_for_eager_type nat
    := existT (PrimitiveHList.hlist (@Datatypes.snd bool Prop))
              [Types.dont_do_again _; Types.dont_do_again _]
              (@eval_nat_rect_arrow, (@eval_nat_rect, tt))%primproj.

  Global Instance eval_rect_list_rules : rules_proofs_for_eager_type list
    := existT (PrimitiveHList.hlist (@Datatypes.snd bool Prop))
              [Types.dont_do_again _; Types.dont_do_again _; Types.dont_do_again _; Types.dont_do_again _; Types.dont_do_again _]
              (@eval_list_rect_arrow, (@eval_list_rect, (@eval_list_case_nil, (@eval_list_case_cons, (@eval_list_nth_default, tt)))))%primproj.

  Global Instance eval_rect_prod_rules : rules_proofs_for_eager_type prod
    := existT (PrimitiveHList.hlist (@Datatypes.snd bool Prop))
              [Types.dont_do_again _]
              (@eval_prod_rect, tt)%primproj.

  Global Instance eval_rect_option_rules : rules_proofs_for_eager_type option
    := existT (PrimitiveHList.hlist (@Datatypes.snd bool Prop))
              [Types.dont_do_again _; Types.dont_do_again _]
              (@eval_option_rect_Some, (@eval_option_rect_None, tt))%primproj.

  Global Instance eval_rect_bool_rules : rules_proofs_for_eager_type bool
    := existT (PrimitiveHList.hlist (@Datatypes.snd bool Prop))
              [Types.dont_do_again _; Types.dont_do_again _]
              (@eval_bool_rect_true, (@eval_bool_rect_false, tt))%primproj.
End Instances.


Load LFindLoad.
From lfind Require Import LFind.

                    From adtind Require Import goal26.

 Require Import Extraction.
 Extract Inductive nat => nat [ "(O)" "S" ].
 Extract Inductive list => list [ "Nil" "Cons" ].
Definition lfind_example_1  := ( Succ (Succ (Succ (Succ (Succ (Succ Zero)))))).
Definition lfind_example_2  := ( Succ (Succ (Succ Zero))).
Definition lfind_example_3  := ( Succ (Succ (Succ Zero))).
Definition lfind_example_4  := ( Succ (Succ Zero)).
Definition lfind_example_5  := ( Succ (Succ (Succ Zero))).
Definition lfind_example_6  := ( Succ (Succ (Succ (Succ (Succ Zero))))).
Definition lfind_example_7  := ( Succ (Succ (Succ (Succ Zero)))).
Definition lfind_example_8  := ( Succ (Succ Zero)).
Definition lfind_example_9  := ( Succ (Succ (Succ Zero))).
Definition lfind_example_10  := ( Succ Zero).
Definition lfind_example_11  := ( Succ Zero).
Definition lfind_example_12  := ( Succ (Succ Zero)).
Definition lfind_example_13  := ( Zero).

                    Extraction "/home/yousef/lemmafinder/benchmark/_lfind_clam_lf_goal26_theorem0_36_plus_comm/lfind_extraction.ml" lfind_example_1 lfind_example_2 lfind_example_3 lfind_example_4 lfind_example_5 lfind_example_6 lfind_example_7 lfind_example_8 lfind_example_9 lfind_example_10 lfind_example_11 lfind_example_12 lfind_example_13 .