Load LFindLoad.
From lfind Require Import LFind.
From QuickChick Require Import QuickChick.
From adtind Require Import goal33.

Derive Show for natural.

              Derive Arbitrary for natural.

              Instance Dec_Eq_natural : Dec_Eq natural.

              Proof. dec_eq. Qed.

Lemma conj19synthconj5 : forall  (lv0 : natural) (lv1 : natural) (lv2 : natural), (@eq natural (mult (plus (mult lv0 lv1) lv1) lv2) (mult lv1 (mult (Succ lv0) lv2))).
Admitted.
QuickChick conj19synthconj5.


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 X Y PX P T : Universe, ((wd_ A B /\ (wd_ PX A /\ (wd_ X PX /\ (wd_ P PX /\ (wd_ P A /\ (wd_ P B /\ (wd_ Y A /\ (wd_ Y B /\ (wd_ X A /\ (wd_ X B /\ (wd_ X P /\ (col_ A B PX /\ (col_ PX A T /\ (col_ P X PX /\ (col_ X PX A /\ col_ Y T P))))))))))))))) -> col_ X A B)).
Proof.
  time tac.
Qed.

End FOFProblem.


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 O E Eprime A B C Aprime Cprime : Universe, ((wd_ O Eprime /\ (wd_ A O /\ (wd_ B O /\ (wd_ C O /\ (wd_ Aprime O /\ (wd_ C O /\ (wd_ Cprime O /\ (wd_ O E /\ (wd_ O Eprime /\ (wd_ E Eprime /\ (col_ O E A /\ (col_ O E B /\ (col_ O E C /\ (col_ O Eprime Aprime /\ (col_ O Eprime C /\ (col_ O Eprime Cprime /\ (col_ O E A /\ (col_ O E B /\ (col_ O E C /\ col_ O Eprime C))))))))))))))))))) -> col_ O E Eprime)).
Proof.
  time tac.
Qed.

End FOFProblem.


(**************************************************************************)
(*   Mechanised Framework for Local Interactions & Distributed Algorithms *)
(*   T. Balabonski, P. Courtieu, L. Rieg, X. Urbain                       *)
(*   PACTOLE project                                                      *)
(*                                                                        *)
(*   This file is distributed under the terms of the CeCILL-C licence.    *)
(*                                                                        *)
(**************************************************************************)

(**************************************************************************)
(**  Mechanised Framework for Local Interactions & Distributed Algorithms
     T. Balabonski, P. Courtieu, L. Rieg, X. Urbain
     PACTOLE project

     This file is distributed under the terms of the CeCILL-C licence.
                                                                          *)
(**************************************************************************)

Set Implicit Arguments.
Require Import Utf8.
Require Import SetoidDec.
Require Import Reals.
Require Import Pactole.Setting.
Require Import Pactole.Spaces.RealMetricSpace.
Require Import Pactole.Spaces.Similarity.

Typeclasses eauto := (bfs).

Section SimilarityCenter.

Context `{Observation}.
Context {VS : RealVectorSpace location}.
Context {RMS : RealMetricSpace location}.
Context `{robot_choice}.
Context `{update_choice}.
Context `{inactive_choice}.

(** Similarities as a frame choice, inside real metric spaces *)
Global Instance FrameChoiceSimilarity : frame_choice (similarity location) := {|
  frame_choice_bijection := @sim_f location _ _ _ _;
  frame_choice_Setoid := similarity_Setoid;
  frame_choice_bijection_compat := f_compat |}.

Definition similarity_da_prop da :=
  forall config g, center (change_frame da config g) == get_location (config (Good g)).

(** When using similarities to change the frame of reference, we need to ensure that
    the center of the similarity is the location of the robot. *)
Definition similarity_da := { sim_da : demonic_action | similarity_da_prop sim_da }.

Instance similarity_da_Setoid : Setoid similarity_da := sig_Setoid _.

Definition proj_sim_da : similarity_da -> demonic_action := @proj1_sig _ _.

Global Instance proj_sim_da_compat : Proper (equiv ==> equiv) proj_sim_da.
Proof using . intros ? ? Heq. apply Heq. Qed.

Definition similarity_center : forall da config g,
  center (change_frame (proj_sim_da da) config g) == get_location (config (Good g))
  := @proj2_sig _ _.

(** Demons are now stream of [similarity_da]s.*)
Definition similarity_demon := Stream.t similarity_da.

(** From a [similarity_demon], we can recover the demon] and its property [similarity_da_prop]. *)
Definition similarity_demon2demon : similarity_demon -> demon := Stream.map proj_sim_da.

Definition similarity_demon2prop : forall d,
  Stream.forever (Stream.instant similarity_da_prop) (similarity_demon2demon d).
Proof. coinduction Hcorec. simpl. unfold proj_sim_da. apply proj2_sig. Defined.

Global Instance similarity_demon2demon_compat :
  Proper (@equiv _ Stream.stream_Setoid ==> @equiv _ Stream.stream_Setoid) similarity_demon2demon.
Proof using . unfold similarity_demon2demon. autoclass. Qed.

Lemma similarity2demon_hd : forall d, Stream.hd (similarity_demon2demon d) = proj_sim_da (Stream.hd d).
Proof using . now intros []. Qed.

Lemma similarity2demon_tl : forall d, Stream.tl (similarity_demon2demon d) = similarity_demon2demon (Stream.tl d).
Proof using . now intros []. Qed.

Lemma similarity2demon_cons : forall da d,
  @equiv _ Stream.stream_Setoid
    (similarity_demon2demon (Stream.cons da d))
    (Stream.cons (proj_sim_da da) (similarity_demon2demon d)).
Proof using . intros. unfold similarity_demon2demon. now rewrite Stream.map_cons. Qed.

(** Conversely, from a [demon] and a proof that [similarity_da_prop] is always true,
    we can build a [similarity_demon]. *)

CoFixpoint demon2similarity_demon : forall (d : demon) (Hd : Stream.forever (Stream.instant similarity_da_prop) d),
  similarity_demon := fun d Hd =>
  Stream.cons
    (exist _ (Stream.hd d) match Hd with | Stream.Always x _ => x end)
    (@demon2similarity_demon (Stream.tl d) (match Hd with | Stream.Always _ x => x end)).

Arguments demon2similarity_demon d Hd : clear implicits.

Lemma demon2similarity_hd : forall d Hd,
  Stream.hd (demon2similarity_demon d Hd) == exist _ (Stream.hd d) (match Hd with Stream.Always x _ => x end).
Proof using . now intros [] []. Qed.

Lemma demon2similarity_tl : forall d Hd,
  Stream.tl (demon2similarity_demon d Hd) == demon2similarity_demon (Stream.tl d) (match Hd with Stream.Always _ x => x end).
Proof using . now intros [] []. Qed.

Theorem demon2demon : forall d Hd,
  @equiv _ Stream.stream_Setoid (similarity_demon2demon (demon2similarity_demon d Hd)) d.
Proof using . coinduction Hcorec. unfold Stream.instant2. now rewrite similarity2demon_hd, demon2similarity_hd. Qed.

End SimilarityCenter.

Coercion proj_sim_da : similarity_da >-> demonic_action.
Coercion similarity_demon2demon : similarity_demon >-> demon.

(*
 *** Local Variables: ***
 *** coq-prog-name: "coqtop" ***
 *** fill-column: 117 ***
 *** End: ***
 *)


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

(***
Modulus : 2^511 - 481
Base: 21 + 7/24
***)

Definition curve : CurveParameters :=
  {|
    sz := 24%nat;
    base := 21 + 7/24;
    bitwidth := 32;
    s := 2^511;
    c := [(1, 481)];
    carry_chains := Some [seq 0 (pred 24); [0; 1]]%nat;

    a24 := None;
    coef_div_modulus := Some 2%nat;

    goldilocks := None;
    karatsuba := None;
    montgomery := false;
    freeze := Some true;
    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.


Load LFindLoad.
From lfind Require Import LFind.
From QuickChick Require Import QuickChick.
From adtind Require Import goal33.

Derive Show for natural.

              Derive Arbitrary for natural.

              Instance Dec_Eq_natural : Dec_Eq natural.

              Proof. dec_eq. Qed.

Lemma conj2eqsynthconj4 : forall  (lv0 : natural) (lv1 : natural), (@eq natural (mult lv0 lv1) (mult lv1 lv0)).
Admitted.
QuickChick conj2eqsynthconj4.


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

(***
Modulus : 2^379 - 19
Base: 23 + 11/16
***)

Definition curve : CurveParameters :=
  {|
    sz := 16%nat;
    base := 23 + 11/16;
    bitwidth := 32;
    s := 2^379;
    c := [(1, 19)];
    carry_chains := Some [seq 0 (pred 16); [0; 1]]%nat;

    a24 := None;
    coef_div_modulus := Some 2%nat;

    goldilocks := None;
    karatsuba := None;
    montgomery := false;
    freeze := Some true;
    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 Export SystemFR.ScalaDepSugar.
Require Export SystemFR.SubtypeExists.
Require Export SystemFR.ReducibilitySubtype.

Opaque reducible_values.

Lemma subtype_union_left:
  forall ρ T1 T2 T,
    [ ρ ⊨ T1 <: T ] ->
    [ ρ ⊨ T2 <: T ] ->
    [ ρ ⊨ T_union T1 T2 <: T ].
Proof.
  repeat step || simp_red.
Qed.

Lemma open_subtype_union_left:
  forall Θ Γ T1 T2 T,
    [ Θ; Γ ⊨ T1 <: T ] ->
    [ Θ; Γ ⊨ T2 <: T ] ->
    [ Θ; Γ ⊨ T_union T1 T2 <: T ].
Proof.
  unfold open_subtype; repeat step; eauto using subtype_union_left.
Qed.

Opaque List.

Lemma open_submatch_helper:
  forall Θ Γ t1 T2 T3 S x y,
    x <> y ->
    ~x ∈ fv S ->
    ~x ∈ fv t1 ->
    ~x ∈ fv T3 ->
    ~x ∈ pfv_context Γ term_var ->
    ~y ∈ fv S ->
    ~y ∈ fv t1 ->
    ~y ∈ fv T3 ->
    ~y ∈ pfv_context Γ term_var ->
    wf t1 0 ->
    [ Θ; Γ ⊨ t1 : List ] ->
    [ Θ; Γ ⊨ T2 <: S ] ->
    [ Θ; (y, List) :: (x, T_top) :: Γ ⊨ open 0 (open 1 T3 (fvar x term_var)) (fvar y term_var) <: S ] ->
    [ Θ; Γ ⊨ List_Match t1 T2 T3 <: S ].
Proof.
  unfold List_Match; intros; apply open_subtype_union_left; steps.
  - unfold open_subtype; repeat step || simp_red_top_level_hyp.
    unfold open_subtype in H2; eauto using subtype_reducible_values.

  - apply open_sub_exists_left_helper with x; repeat step || list_utils.
    apply open_sub_exists_left_helper with y;
      repeat step || list_utils || fv_open || open_none.
    rewrite (open_none t1) by eauto with wf.
    unfold open_subtype in H11.
    unfold open_subtype; repeat step || simp_red_top_level_hyp.
Qed.

Lemma open_submatch:
  forall Γ t1 T2 T3 S x y,
    x <> y ->
    ~x ∈ fv S ->
    ~x ∈ fv t1 ->
    ~x ∈ fv T3 ->
    ~x ∈ pfv_context Γ term_var ->
    ~y ∈ fv S ->
    ~y ∈ fv t1 ->
    ~y ∈ fv T3 ->
    ~y ∈ pfv_context Γ term_var ->
    wf t1 0 ->
    [ Γ ⊫ t1 : List ] ->
    [ Γ ⊫ T2 <: S ] ->
    [ (y, List) :: (x, T_top) :: Γ ⊫ open 0 (open 1 T3 (fvar x term_var)) (fvar y term_var) <: S ] ->
    [ Γ ⊫ List_Match t1 T2 T3 <: S ].
Proof.
  eauto using open_submatch_helper.
Qed.


(**************************************************************************
* TLC: A library for Coq                                                  *
* Option data-structure
**************************************************************************)

Set Implicit Arguments.
Require Import LibTactics LibReflect.
Generalizable Variables A.

(** Fixing implicit arguments *)

Implicit Arguments Some [[A]].
Implicit Arguments None [[A]].

(* ********************************************************************** *)
(** * Inhabited and comparable *)

Instance option_inhab : forall A, Inhab (option A).
Proof using. intros. apply (prove_Inhab None). Qed.

Definition option_compare `{Comparable A} (o1 o2 : option A) :=
  match o1, o2 with
  | None, None => true
  | Some v1, Some v2 => decide (v1 = v2)
  | _, _ => false
  end.

Global Instance option_comparable : forall `{Comparable A},
  Comparable (option A).
Proof using.
  intros.
  applys (comparable_beq option_compare).
  destruct x; destruct y; simpl; rew_refl; iff; auto_false*; congruence.
Qed.

(* ********************************************************************** *)
(** * Operations and their properties *)

(* ---------------------------------------------------------------------- *)
(** ** Definitions *)

(** [is_some o] holds when [o] is of the form [Some x] *)

Definition is_some A (o:option A) :=
  match o with
  | None => false
  | Some _ => true
  end.

(** [unsome_default d o] returns the content of the option, and returns [d]
    in case the option in [None]. *)

Definition unsome_default A d (o:option A) :=
  match o with
  | None => d
  | Some x => x
  end.

(** [unsome o] returns the content of the option, and returns an arbitrary
    value in case the option in [None]. *)

Definition unsome `{Inhab A} :=
  unsome_default arbitrary.

(** [map f o] takes an option and returns an option, and maps the function
    [f] to the content of the option if it has one. *)

Definition map A B (f : A -> B) o :=
  match o with
  | None => None
  | Some x => Some (f x)
  end.

(** [map_on o f] is the same as [map f o], only the arguments are swapped. *)

Definition map_on A B o (f : A -> B) :=
  map f o.

(** [apply f o] optionnaly applies a function of type [A -> option B] *)
(* --todo: find a more explicit name *)

Definition apply A B (f : A -> option B) o :=
  match o with
  | None => None
  | Some x => f x
  end.

(** [apply_on o f] is the same as [apply f o] *)

Definition apply_on A B o (f : A -> option B) :=
  apply f o.

(* ---------------------------------------------------------------------- *)
(** ** Properties *)

Lemma apply_on_inv : forall A B (f : A->option B) x y,
  apply_on x f = Some y ->
  exists z, x = Some z /\ f z = Some y.
Proof using. destruct x; simpl; introv H; inverts* H. Qed.

Implicit Arguments apply_on_inv [A B f x y].

Lemma apply_on_inv_none : forall A B (f : A->option B) x,
  apply_on x f = None ->
  x = None \/ exists y, x = Some y /\ f y = None.
Proof. destruct x; simpl; introv H; inverts* H. Qed.

Lemma map_inv : forall A B (f : A->B) x y,
  map f x = Some y ->
  exists z, x = Some z /\ y = f z.
Proof using. destruct x; simpl; introv H; inverts* H. Qed.

Implicit Arguments map_inv [A B f x y].

Lemma map_on_inv : forall A B (f : A->B) x y,
  map_on x f = Some y ->
  exists z, x = Some z /\ y = f z.
Proof using. destruct x; simpl; introv H; inverts* H. Qed.

Implicit Arguments map_on_inv [A B f x y].

Lemma option_map_none_inv : forall A B (f : A -> B) o,
  map f o = None -> o = None.
Proof. introv E. destruct~ o; tryfalse. Qed.


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 Bprime Cprime T : Universe, ((wd_ A Bprime /\ (wd_ A Cprime /\ (wd_ B Bprime /\ (wd_ A C /\ (wd_ C Cprime /\ (wd_ B C /\ (wd_ Bprime Cprime /\ (wd_ Cprime B /\ (wd_ A B /\ (wd_ Bprime C /\ (col_ A Bprime Cprime /\ (col_ A B C /\ (col_ T B Bprime /\ col_ A T Cprime))))))))))))) -> col_ A Bprime T)).
Proof.
  time tac.
Qed.

End FOFProblem.