Skip to content

Extend Scheme command to support custom schemes#21271

Closed
felixL-K wants to merge 6 commits intorocq-prover:masterfrom
felixL-K:generalize_schemes_try_rebase
Closed

Extend Scheme command to support custom schemes#21271
felixL-K wants to merge 6 commits intorocq-prover:masterfrom
felixL-K:generalize_schemes_try_rebase

Conversation

@felixL-K
Copy link

@felixL-K felixL-K commented Nov 4, 2025

This pull request comes at the conclusion of my internship with Hugo Herbelin and aims to extend the
Scheme command in Rocq to allow users to define new schemes beyond the built-in ones
(Induction, Minimality, Elimination, Case, etc.).

It also unifies the previously distinct implementations of Equality and Boolean Equality schemes,
bringing them into the generalised scheme mechanism.

Previously, the compiler only allowed a fixed set of elimination schemes, by generalising them, we
open the door for user-defined schemes.

You can now also define schemes that weren’t accessible before.
For example: Scheme Right2Left Dependent Rewrite for ind Sort Type

To do that :

  • A key revision is that each scheme in my branch is now represented internally by a triplet:
    • A string list representing the scheme name (e.g., ["Induction"], ["Boolean";"Equality"], …)
    • An UnivGen.QualityOrSet.t option representing the universe sort/type on which the scheme operates
    • A bool flag indicating whether the scheme is mutual (true) or individual (false)
  • Replaced the former do_mutual_induction_scheme in vernac/indschemes.ml with a new do_scheme function
    that handles both individual and mutual schemes.
  • Merged Equality and Boolean Equality schemes into the general scheme machinery,no longer special-cased.
  • I couldn't merge the new Rewriting scheme into the general scheme machinery
  • Added tests/adjustments where necessary to adapt to the new mechanism.

Please review especially the new scheme registration logic and the handling of mutual vs individual
cases.

  • Added / updated test-suite.
  • Added changelog.
  • Added / updated documentation.
    • Documented any new / changed user messages.
    • Updated documented syntax by running make doc_gram_rsts.

@coqbot-app coqbot-app bot added the needs: full CI The latest GitLab pipeline that ran was a light CI. Say "@coqbot run full ci" to get a full CI. label Nov 4, 2025
@SkySkimmer
Copy link
Contributor

@coqbot run full ci

@coqbot-app coqbot-app bot removed the needs: full CI The latest GitLab pipeline that ran was a light CI. Say "@coqbot run full ci" to get a full CI. label Nov 7, 2025
@github-actions github-actions bot added the needs: rebase Should be rebased on the latest master to solve conflicts or have a newer CI run. label Nov 10, 2025
@SkySkimmer SkySkimmer added the needs: fixing The proposed code change is broken. label Nov 12, 2025
@SkySkimmer
Copy link
Contributor

Doesn't build & needs a rebase to fix conflicts (I guess conflicts from #21241)

@felixL-K felixL-K force-pushed the generalize_schemes_try_rebase branch from 50fa022 to e22a90f Compare November 17, 2025 14:26
@coqbot-app coqbot-app bot added needs: full CI The latest GitLab pipeline that ran was a light CI. Say "@coqbot run full ci" to get a full CI. and removed needs: rebase Should be rebased on the latest master to solve conflicts or have a newer CI run. labels Nov 17, 2025
@SkySkimmer SkySkimmer added needs: squashing Some commits should be squashed together. and removed needs: fixing The proposed code change is broken. labels Nov 17, 2025
@felixL-K felixL-K force-pushed the generalize_schemes_try_rebase branch from e22a90f to daa1773 Compare November 17, 2025 15:44
@felixL-K felixL-K marked this pull request as ready for review November 17, 2025 20:01
@felixL-K felixL-K requested review from a team as code owners November 17, 2025 20:01
@SkySkimmer SkySkimmer removed the needs: squashing Some commits should be squashed together. label Nov 18, 2025
@SkySkimmer
Copy link
Contributor

@coqbot run full ci

@coqbot-app coqbot-app bot removed the needs: full CI The latest GitLab pipeline that ran was a light CI. Say "@coqbot run full ci" to get a full CI. label Nov 18, 2025

Module TestExport.
#[export] Register Scheme paths_rew_r_dep as rew_r_dep for eq.
#[export] Register Scheme paths_rew_r_dep as Left2Right Dependent Rewrite for eq.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we probably want to provide some compatibility mapping for Register Scheme so that the old scheme names keep working alongside the new ones for at least version

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I add a function like:

let old_scheme_name_to_new sch =
  match sch with
  | ["rew_r_dep"] -> ["Left2Right"; "Dependent"; "Rewrite"]
  | ["rect_dep"] | ["rec_dep"] -> ["Induction"]
  | … 
  | _ -> CErrors.user_err Pp.(str ("unknown scheme kind " ^ String.concat " " sch))

and wrap it in a deprecation warning?

Right now I changed the Register command so that it always requires Sort @qualid at the end, so maybe compatibility for old scheme names is no longer necessary ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old syntax should keep working (deprecated) for at least a version
so yes there should be some old_scheme_name_to_new translation, but it should also return the sort (and Register shouldn't be given a sort when called with old scheme names)

val all_schemes : unit -> Constant.t CString.Map.t Indmap_env.t
module Key : sig

type t = (string list * UnivGen.QualityOrSet.t option * bool)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not entirely sure QualityOrSet is the right type for this, we may want a type which does not include sort variables

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@herbelin what do you think about this ?
What type should we use ? Should I create a new type or keep QualityOrSet ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And yet, you want to be able to distinguish SortPoly or Not.
A basic algebraic type would probably suffice

@coqbot-app
Copy link
Contributor

coqbot-app bot commented Nov 18, 2025

Minimized File /home/runner/work/run-coq-bug-minimizer/run-coq-bug-minimizer/builds/coq/coq-failing/_build_ci/hott/theories/Limits/Pullback.v in 50m 27s (from ci-hott) (full log on GitHub Actions - verbose log)

We are collecting data on the user experience of the Coq Bug Minimizer.
If you haven't already filled the survey for this PR, please fill out our short survey!

🌟 Minimized Coq File (consider adding this file to the test-suite)
(* -*- mode: coq; coq-prog-args: ("-emacs" "-q" "-noinit" "-indices-matter" "-w" "-deprecated-native-compiler-option" "-native-compiler" "no" "-coqlib" "/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq//" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/hott/theories" "HoTT" "-Q" "/github/workspace/cwd" "Top" "-Q" "/github/workspace/builds/coq/coq-failing/_build_ci/hott/contrib" "HoTT.Contrib" "-Q" "/github/workspace/builds/coq/coq-failing/_build_ci/hott/test" "HoTT.Tests" "-Q" "/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Ltac2" "Ltac2" "-top" "HoTT.Limits.Pullback") -*- *)
(* File reduced by coq-bug-minimizer from original input, then from 498 lines to 67 lines, then from 81 lines to 723 lines, then from 729 lines to 118 lines, then from 129 lines to 182 lines, then from 189 lines to 122 lines, then from 133 lines to 924 lines, then from 931 lines to 146 lines, then from 156 lines to 196 lines, then from 203 lines to 157 lines, then from 168 lines to 1050 lines, then from 1056 lines to 221 lines, then from 232 lines to 371 lines, then from 378 lines to 231 lines, then from 242 lines to 1803 lines, then from 1809 lines to 246 lines, then from 257 lines to 969 lines, then from 973 lines to 305 lines, then from 316 lines to 1129 lines, then from 1135 lines to 434 lines, then from 445 lines to 532 lines, then from 539 lines to 447 lines, then from 457 lines to 772 lines, then from 776 lines to 478 lines, then from 489 lines to 477 lines, then from 489 lines to 378 lines, then from 390 lines to 378 lines *)
(* coqc version 9.2+alpha compiled with OCaml 4.14.2
   coqtop version 9.2+alpha
   Expected coqc runtime on this file: 1.262 sec
   Expected coqc peak memory usage on this file: 370688.0 kb *)

Require Corelib.Init.Ltac.
Inductive False : Prop := .
Axiom proof_admitted : False.
Tactic Notation "admit" := abstract case proof_admitted.
Reserved Notation "x -> y" (at level 99, right associativity, y at level 200).

Reserved Notation "x = y  :>  T"
(at level 70, y at next level, no associativity).

Reserved Notation "{ x : A  & P }" (at level 0, x at level 99).
Reserved Notation "p @ q" (at level 20).
Reserved Notation "f == g" (at level 70, no associativity).

Reserved Notation "A <~> B" (at level 85).
Reserved Notation "g 'oE' f" (at level 40, left associativity).
Reserved Notation "g 'o' f" (at level 40, left associativity).
Declare Scope fibration_scope.
Delimit Scope function_scope with function.
Delimit Scope type_scope with type.
Delimit Scope equiv_scope with equiv.
Delimit Scope path_scope with path.
Global Open Scope equiv_scope.
Global Open Scope path_scope.
Global Open Scope fibration_scope.
Global Open Scope type_scope.
Declare ML Module "ltac_plugin:coq-core.plugins.ltac".

Global Set Default Proof Mode "Classic".

Global Set Universe Polymorphism.

Global Unset Strict Universe Declaration.

Global Set Keyed Unification.
Create HintDb typeclass_instances discriminated.

Notation "A -> B" := (forall (_ : A), B) : type_scope.

Definition Relation (A : Type) := A -> A -> Type.

Class Reflexive {A} (R : Relation A) :=
  reflexivity : forall x : A, R x x.

Class Symmetric {A} (R : Relation A) :=
  symmetry : forall x y, R x y -> R y x.

Ltac old_reflexivity := reflexivity.
Tactic Notation "reflexivity" :=
  old_reflexivity
|| (intros;
  let R := match goal with |- ?R ?x ?y => constr:(R) end in
  let pre_proof_term_head := constr:(@reflexivity _ R _) in
  let proof_term_head := (eval cbn in pre_proof_term_head) in
  apply (proof_term_head : forall x, R x x)).

Tactic Notation "symmetry" :=
  let R := match goal with |- ?R ?x ?y => constr:(R) end in
  let x := match goal with |- ?R ?x ?y => constr:(x) end in
  let y := match goal with |- ?R ?x ?y => constr:(y) end in
  let pre_proof_term_head := constr:(@symmetry _ R _) in
  let proof_term_head := (eval cbn in pre_proof_term_head) in
  refine (proof_term_head y x _); change (R y x).

Notation Type0 := Set.

Record sig {A} (P : A -> Type) := exist {
  proj1 : A ;
  proj2 : P proj1 ;
}.

Arguments exist {A}%_type P%_type _ _.
Arguments proj1 {A P} _ / .
Arguments proj2 {A P} _ / .
Notation "{ x : A  & P }" := (sig (fun x:A => P)) : type_scope.

Notation "( x ; y )" := (exist _ x y) : fibration_scope.

Notation pr1 := proj1.
Notation pr2 := proj2.

Notation "x .1" := (pr1 x) : fibration_scope.
Notation "x .2" := (pr2 x) : fibration_scope.

Notation idmap := (fun x => x).

Notation compose := (fun g f x => g (f x)).

Notation "g 'o' f" := (compose g%function f%function) : function_scope.

Inductive paths {A : Type} (a : A) : A -> Type :=
  idpath : paths a a.

Arguments idpath {A a} , [A] a.

Notation "x = y :> A" := (@paths A x y) : type_scope.
Notation "x = y" := (x = y :>_) : type_scope.
Definition inverse {A : Type} {x y : A} (p : x = y) : y = x.
Admitted.
Instance symmetric_paths {A} : Symmetric (@paths A) | 0.
exact (@inverse A).
Defined.

Definition concat {A : Type} {x y z : A} (p : x = y) (q : y = z) : x = z :=
  match p, q with idpath, idpath => idpath end.

Notation "1" := idpath : path_scope.

Notation "p @ q" := (concat p%path q%path) : path_scope.

Notation "p ^" := (inverse p%path) : path_scope.
Definition ap {A B : Type} (f : A -> B) {x y : A} (p : x = y) : f x = f y.
Admitted.

Definition pointwise_paths A (P : A -> Type) (f g : forall x, P x)
  := forall x, f x = g x.

Instance symmetric_pointwise_paths A P
  : Symmetric (pointwise_paths A P).
Proof.
  intros ? ? p ?; symmetry; apply p.
Defined.

Global Arguments pointwise_paths {A}%_type_scope {P} (f g)%_function_scope.

Notation "f == g" := (pointwise_paths f g) : type_scope.

Class IsEquiv {A B : Type} (f : A -> B) := {
  equiv_inv : B -> A ;
  eisretr : f o equiv_inv == idmap ;
  eissect : equiv_inv o f == idmap ;
  eisadj : forall x : A, eisretr (f x) = ap f (eissect x) ;
}.

Record Equiv A B := {
  equiv_fun : A -> B ;
  equiv_isequiv :: IsEquiv equiv_fun
}.

Notation "A <~> B" := (Equiv A B) : type_scope.

Inductive trunc_index : Type0 :=
| minus_two : trunc_index
| trunc_S : trunc_index -> trunc_index.

Inductive IsTrunc_internal (A : Type@{u}) : trunc_index -> Type@{u} :=
| Build_Contr : forall (center : A) (contr : forall y, center = y), IsTrunc_internal A minus_two
| istrunc_S : forall {n:trunc_index}, (forall x y:A, IsTrunc_internal (x = y) n) -> IsTrunc_internal A (trunc_S n).

Notation IsTrunc n A := (IsTrunc_internal A n).

Notation Contr A := (IsTrunc minus_two A).

Tactic Notation "do_with_holes" tactic3(x) uconstr(p) :=
  x uconstr:(p) ||
  x uconstr:(p _) ||
  x uconstr:(p _ _) ||
  x uconstr:(p _ _ _) ||
  x uconstr:(p _ _ _ _) ||
  x uconstr:(p _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) ||
  x uconstr:(p _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _).
Class IsGlobalAxiom (A : Type) : Type0 := {}.

Ltac is_global_axiom A := let _ := constr:(_ : IsGlobalAxiom A) in idtac.

Ltac global_axiom := try match goal with
    | |- ?G  => is_global_axiom G; exact _
end.

Tactic Notation "nrefine" uconstr(term) := notypeclasses refine term; global_axiom.

Tactic Notation "snrefine" uconstr(term) := simple notypeclasses refine term; global_axiom.

Tactic Notation "rapply" uconstr(term)
  := do_with_holes ltac:(fun x => assert_succeeds (nrefine x); refine x) term.
Definition inv_V {A : Type} {x y : A} (p : x = y) :
  p^^ = p.
Admitted.
Definition Contr_ind@{u v|} (A : Type@{u}) (P : Contr A -> Type@{v})
  (H : forall (center : A) (contr : forall y, center = y), P (Build_Contr A center contr))
  (C : Contr A)
  : P C.
Admitted.
Instance reflexive_equiv : Reflexive Equiv | 0.
Admitted.
Definition equiv_compose' {A B C : Type} (g : B <~> C) (f : A <~> B)
  : A <~> C.
Admitted.

Notation "g 'oE' f" := (equiv_compose' g%equiv f%equiv) : equiv_scope.

Section Adjointify.

  Context {A B : Type} (f : A -> B) (g : B -> A).
  Context (isretr : f o g == idmap) (issect : g o f == idmap).
Definition equiv_adjointify : A <~> B.
Admitted.

End Adjointify.

Theorem equiv_inverse {A B : Type} : (A <~> B) -> (B <~> A).
Admitted.

Notation "e ^-1" := (@equiv_inverse _ _ e) : equiv_scope.
Instance symmetric_equiv : Symmetric Equiv | 0.
Admitted.

Ltac decomposing_intros :=
  let x := fresh in
  intros x; hnf in x; cbn in x;
  try lazymatch type of x with
  | ?a = ?b => idtac
  | forall y:?A, ?B => idtac
  | Contr ?A => revert x; match goal with |- (forall y, ?P y) => snrefine (Contr_ind A P _) end
  | _ => elim x; clear x
  end;
  try decomposing_intros.

Ltac multi_assumption :=
  multimatch goal with

    [ H : ?A |- _ ] => exact H
  end.

Ltac build_record :=
  cbn; multi_assumption + (unshelve econstructor; build_record).

Ltac make_equiv :=
  snrefine (equiv_adjointify _ _ _ _);
    [ decomposing_intros; build_record
    | decomposing_intros; build_record
    | decomposing_intros; exact idpath
    | decomposing_intros; exact idpath ].

Generalizable Variables X A B C f g n.
Definition functor_sigma `{P : A -> Type} `{Q : B -> Type}
  (f : A -> B) (g : forall a, P a -> Q (f a))
  : sig P -> sig Q.
exact (fun u => (f u.1 ; g u.1 u.2)).
Defined.
Definition equiv_functor_sigma_id `{P : A -> Type} `{Q : A -> Type}
  (g : forall a, P a <~> Q a)
  : sig P <~> sig Q.
Admitted.

Local Unset Elimination Schemes.

Cumulative Inductive PathSquare {A} : forall a00 {a10 a01 a11 : A},
  a00 = a10 -> a01 = a11 -> a00 = a01 -> a10 = a11 -> Type
  := sq_id : forall {x : A},
    PathSquare x 1 1 1 1.
Arguments PathSquare {A _ _ _ _}.

#[warnings="-unsupported-attributes",register=no] Scheme PathSquare_ind := Induction for PathSquare Sort Type.

Definition equiv_sq_tr {A : Type} {a00 a10 a01 a11 : A}
  {px0 : a00 = a10} {px1 : a01 = a11} {p0x : a00 = a01} {p1x : a10 = a11}
  : PathSquare px0 px1 p0x p1x <~> PathSquare p0x p1x px0 px1.
Admitted.

Notation sq_tr := equiv_sq_tr.

Section MovePaths.
  Context {A : Type} {x x00 x20 x02 x22 : A}
  {f10 : x00 = x20} {f12 : x02 = x22} {f01 : x00 = x02} {f21 : x20 = x22}.

  Definition equiv_sq_move_23 {f12'' : x02 = x} {f12' : x = x22}
    : PathSquare f10 (f12'' @ f12') f01 f21 <~> PathSquare f10 f12' (f01 @ f12'') f21.
admit.
Defined.

  Definition equiv_sq_move_14 {f10'' : x00 = x} {f10' : x = x20}
    : PathSquare (f10'' @ f10') f12 f01 f21 <~> PathSquare f10'' f12 f01 (f10' @ f21).
admit.
Defined.

  Definition equiv_sq_move_24 {f12'' : x02 = x} {f12' : x22 = x}
    : PathSquare f10 (f12'' @ f12'^) f01 f21 <~> PathSquare f10 f12'' f01 (f21 @ f12').
admit.
Defined.

  Definition equiv_sq_move_31 {f10'' : x00 = x} {f10' : x = x20}
    : PathSquare f10' f12 (f10''^ @ f01) f21 <~> PathSquare (f10'' @ f10') f12 f01 f21.
admit.
Defined.

End MovePaths.

Notation sq_move_23 := equiv_sq_move_23.
Notation sq_move_14 := equiv_sq_move_14.
Notation sq_move_24 := equiv_sq_move_24.
Notation sq_move_31 := equiv_sq_move_31.

Definition Pullback {A B C} (f : B -> A) (g : C -> A)
  := { b : B & { c : C & f b = g c }}.

Section Functor_Pullback.

  Context {A1 B1 C1 A2 B2 C2}
          (f1 : B1 -> A1) (g1 : C1 -> A1)
          (f2 : B2 -> A2) (g2 : C2 -> A2)
          (h : A1 -> A2) (k : B1 -> B2) (l : C1 -> C2)
          (p : f2 o k == h o f1) (q : g2 o l == h o g1).
Definition functor_pullback : Pullback f1 g1 -> Pullback f2 g2.
exact (functor_sigma k
        (fun b1 => (functor_sigma l
                     (fun c1 e1 => p b1 @ ap h e1 @ (q c1)^)))).
Defined.

End Functor_Pullback.

Definition equiv_path_pullback {A B C} (f : B -> A) (g : C -> A)
           (x y : Pullback f g)
  : { p : x.1 = y.1 & { q : x.2.1 = y.2.1 & PathSquare (ap f p) (ap g q) x.2.2 y.2.2 } }
      <~> (x = y).
Admitted.

Section Pullback3x3.

  Context
    (A00 A02 A04 A20 A22 A24 A40 A42 A44 : Type)
    (f01 : A00 -> A02) (f03 : A04 -> A02)
    (f10 : A00 -> A20) (f12 : A02 -> A22) (f14 : A04 -> A24)
    (f21 : A20 -> A22) (f23 : A24 -> A22)
    (f30 : A40 -> A20) (f32 : A42 -> A22) (f34 : A44 -> A24)
    (f41 : A40 -> A42) (f43 : A44 -> A42)
    (H11 : f12 o f01 == f21 o f10) (H13 : f12 o f03 == f23 o f14)
    (H31 : f32 o f41 == f21 o f30) (H33 : f32 o f43 == f23 o f34).

  Let fX1 := functor_pullback f10 f30 f12 f32 f21 f01 f41 H11 H31.
  Let fX3 := functor_pullback f14 f34 f12 f32 f23 f03 f43 H13 H33.
  Let f1X := functor_pullback f01 f03 f21 f23 f12 f10 f14 (symmetry _ _ H11) (symmetry _ _ H13).
  Let f3X := functor_pullback f41 f43 f21 f23 f32 f30 f34 (symmetry _ _ H31) (symmetry _ _ H33).

  Theorem pullback3x3 : Pullback fX1 fX3 <~> Pullback f1X f3X.
  Proof.
    refine (_ oE _ oE _).
    1,3:do 2 (rapply equiv_functor_sigma_id; intro).
    1:apply equiv_path_pullback.
    1:symmetry; apply equiv_path_pullback.
    refine (_ oE _).
    {
 do 4 (rapply equiv_functor_sigma_id; intro).
      refine (sq_tr oE _).
      refine (sq_move_14^-1 oE _).
      refine (sq_move_31 oE _).
      refine (sq_move_24^-1 oE _).
      refine (sq_move_23^-1 oE _).
      rewrite 2 inv_V.
      reflexivity.
}
    make_equiv.
🛠️ Intermediate Coq File (useful for debugging if minimization did not go as far as you wanted)
🛠️ 📜 Intermediate Coq File log (useful for debugging if minimization did not go as far as you wanted)
📜 Build Log (contains the Coq error message) (truncated to last 8.0KiB; full 2.9MiB file on GitHub Actions Artifacts under build.log)
failing/_build_ci/hott/theories HoTT theories/Categories/FunctorCategory/Dual.v 
MINIMIZER_DEBUG_EXTRA: coqpath: 
MINIMIZER_DEBUG_EXTRA: ocamlpath: /github/workspace/builds/coq/coq-failing/_install_ci/lib:
MINIMIZER_DEBUG_EXTRA: pwd: PWD=/github/workspace/builds/coq/coq-failing/_build_ci/hott
MINIMIZER_DEBUG_EXTRA: exec: /github/workspace/builds/coq/coq-failing/_install_ci/bin/rocq.orig compile -time-file /github/workspace/builds/coq/coq-failing/_build_ci/hott/theories/Categories/FunctorCategory/Dual.v.timing -q -noinit -indices-matter -w -deprecated-native-compiler-option -native-compiler no -Q /github/workspace/builds/coq/coq-failing/_build_ci/hott/contrib HoTT.Contrib -Q /github/workspace/builds/coq/coq-failing/_build_ci/hott/test HoTT.Tests -R /github/workspace/builds/coq/coq-failing/_build_ci/hott/theories HoTT theories/Categories/FunctorCategory/Dual.v 
MINIMIZER_DEBUG_EXTRA: coqlib: Warning: Deprecated environment variable COQLIB, use ROCQLIB instead.
/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq//
MINIMIZER_DEBUG: info: /tmp/tmp-coqbot-minimizer.tpHg4zpbw7
MINIMIZER_DEBUG: files:  theories/Categories/FunctorCategory/Dual.v /github/workspace/builds/coq/coq-failing/_build_ci/hott/theories/Categories/FunctorCategory/Dual.v
Warning, feedback message received but no listener to handle it!
Warning: Deprecated environment variable COQLIB, use ROCQLIB instead.
[deprecated-coq-env-var,deprecated-since-9.0,deprecated,default]Warning, feedback message received but no listener to handle it!
Warning: Deprecated environment variable COQLIB, use ROCQLIB instead.
[deprecated-coq-env-var,deprecated-since-9.0,deprecated,default]
Warning: Deprecated environment variable COQCORELIB,
use ROCQRUNTIMELIB instead.
[deprecated-coq-env-var,deprecated-since-9.0,deprecated,default]
theories/Categories/FunctorCategory/Dual.vo (real: 0.15, user: 0.08, sys: 0.06, mem: 158900 ko)
ROCQ compile theories/Categories/Grothendieck/ToSet/Core.v
File "./theories/Limits/Pullback.v", line 432, characters 4-14:
Error: Not an inductive definition.

Command exited with non-zero status 1
theories/Limits/Pullback.vo (real: 0.48, user: 0.38, sys: 0.09, mem: 359496 ko)
make[2]: *** [Makefile.coq:813: theories/Limits/Pullback.vo] Error 1
make[2]: *** [theories/Limits/Pullback.vo] Deleting file 'theories/Limits/Pullback.glob'
make[2]: *** Waiting for unfinished jobs....
MINIMIZER_DEBUG_EXTRA: coqc: /github/workspace/builds/coq/coq-failing/_install_ci/bin/////rocq
MINIMIZER_DEBUG_EXTRA: original invocation: compile -time-file theories/Categories/Grothendieck/ToSet/Core.v.timing -q -noinit -indices-matter -w -deprecated-native-compiler-option -native-compiler no -Q contrib HoTT.Contrib -Q test HoTT.Tests -R theories HoTT theories/Categories/Grothendieck/ToSet/Core.v 
MINIMIZER_DEBUG_EXTRA: new invocation: /github/workspace/builds/coq/coq-failing/_install_ci/bin/rocq.orig compile -time-file /github/workspace/builds/coq/coq-failing/_build_ci/hott/theories/Categories/Grothendieck/ToSet/Core.v.timing -q -noinit -indices-matter -w -deprecated-native-compiler-option -native-compiler no -Q /github/workspace/builds/coq/coq-failing/_build_ci/hott/contrib HoTT.Contrib -Q /github/workspace/builds/coq/coq-failing/_build_ci/hott/test HoTT.Tests -R /github/workspace/builds/coq/coq-failing/_build_ci/hott/theories HoTT theories/Categories/Grothendieck/ToSet/Core.v 
MINIMIZER_DEBUG_EXTRA: coqpath: 
MINIMIZER_DEBUG_EXTRA: ocamlpath: /github/workspace/builds/coq/coq-failing/_install_ci/lib:
MINIMIZER_DEBUG_EXTRA: pwd: PWD=/github/workspace/builds/coq/coq-failing/_build_ci/hott
MINIMIZER_DEBUG_EXTRA: exec: /github/workspace/builds/coq/coq-failing/_install_ci/bin/rocq.orig compile -time-file /github/workspace/builds/coq/coq-failing/_build_ci/hott/theories/Categories/Grothendieck/ToSet/Core.v.timing -q -noinit -indices-matter -w -deprecated-native-compiler-option -native-compiler no -Q /github/workspace/builds/coq/coq-failing/_build_ci/hott/contrib HoTT.Contrib -Q /github/workspace/builds/coq/coq-failing/_build_ci/hott/test HoTT.Tests -R /github/workspace/builds/coq/coq-failing/_build_ci/hott/theories HoTT theories/Categories/Grothendieck/ToSet/Core.v 
MINIMIZER_DEBUG_EXTRA: coqlib: Warning: Deprecated environment variable COQLIB, use ROCQLIB instead.
/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq//
MINIMIZER_DEBUG: info: /tmp/tmp-coqbot-minimizer.AkiERtbPFL
MINIMIZER_DEBUG: files:  theories/Categories/Grothendieck/ToSet/Core.v /github/workspace/builds/coq/coq-failing/_build_ci/hott/theories/Categories/Grothendieck/ToSet/Core.v
Warning, feedback message received but no listener to handle it!
Warning: Deprecated environment variable COQLIB, use ROCQLIB instead.
[deprecated-coq-env-var,deprecated-since-9.0,deprecated,default]Warning, feedback message received but no listener to handle it!
Warning: Deprecated environment variable COQLIB, use ROCQLIB instead.
[deprecated-coq-env-var,deprecated-since-9.0,deprecated,default]
Warning: Deprecated environment variable COQCORELIB,
use ROCQRUNTIMELIB instead.
[deprecated-coq-env-var,deprecated-since-9.0,deprecated,default]
File "./theories/Categories/Grothendieck/ToSet/Core.v", line 50, characters 8-16:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
theories/Categories/Grothendieck/ToSet/Core.vo (real: 0.15, user: 0.08, sys: 0.07, mem: 165912 ko)
make[1]: *** [Makefile.coq:411: all] Error 2
make: *** [Makefile:21: invoke-coqmakefile] Error 2
+ code=2
+ printf '\n%s exit code: %s\n' hott 2
+ '[' hott '!=' stdlib_test ']'
+ echo 'Aggregating timing log...'
Aggregating timing log...
+ echo

+ tools/make-one-time-file.py --real hott.log
    Time |  Peak Mem | File Name                                                   
-----------------------------------------------------------------------------------
0m06.04s | 370796 ko | Total Time / Peak Mem                                       
-----------------------------------------------------------------------------------
0m00.91s | 359196 ko | Categories/ExponentialLaws/Law4/Law.vo                      
0m00.89s | 364772 ko | Categories/Category/Sigma/Univalent.vo                      
0m00.69s | 370796 ko | Extensions.vo                                               
0m00.48s | 359496 ko | Limits/Pullback.vo                                          
0m00.29s | 350380 ko | Categories/ExponentialLaws/Law4/Functors.vo                 
0m00.29s | 350640 ko | Categories/Functor/Composition/Laws.vo                      
0m00.20s | 226624 ko | Categories/NaturalTransformation/Isomorphisms.vo            
0m00.17s | 193160 ko | Categories/ExponentialLaws/Law0.vo                          
0m00.17s | 187732 ko | Categories/NaturalTransformation/Composition/Laws.vo        
0m00.16s | 141268 ko | Categories/Category/Sigma/OnObjects.vo                      
0m00.15s | 154756 ko | Categories/Adjoint/UnitCounit.vo                            
0m00.15s | 158900 ko | Categories/FunctorCategory/Dual.vo                          
0m00.15s | 165912 ko | Categories/Grothendieck/ToSet/Core.vo                       
0m00.15s | 168876 ko | Categories/InitialTerminalCategory/Functors.vo              
0m00.13s | 129048 ko | Categories/Cat/Morphisms.vo                                 
0m00.13s | 140140 ko | Categories/Functor/Prod/Functorial.vo                       
0m00.13s | 128688 ko | Categories/SetCategory/Core.vo                              
0m00.12s | 109892 ko | Categories/FunctorCategory/Core.vo                          
0m00.12s | 123848 ko | Categories/InitialTerminalCategory/NaturalTransformations.vo
0m00.12s | 114188 ko | Categories/NaturalTransformation/Composition/Functorial.vo  
0m00.12s | 126176 ko | Categories/NaturalTransformation/Sum.vo                     
0m00.11s |  95840 ko | Categories/Category/Subcategory/Wide.vo                     
0m00.11s |  95992 ko | Categories/CategoryOfSections.vo                            
0m00.10s |  95984 ko | Categories/Category/Subcategory/Full.vo                     
+ '[' '' ']'
+ exit 2
/github/workspace/builds/coq /github/workspace
::endgroup::
📜 🔎 Minimization Log (truncated to last 8.0KiB; full 2.5MiB file on GitHub Actions Artifacts under bug.log)
n-fatal error: Failed to remove Sections and preserve the error.  
The new error was:
Deprecated environment variable COQCORELIB, use ROCQRUNTIMELIB instead.
Warning: Deprecated environment variable COQCORELIB,
use ROCQRUNTIMELIB instead.
[deprecated-coq-env-var,deprecated-since-9.0,deprecated,default]
File "/tmp/tmp6dvl5_pq/HoTT/Limits/Pullback.v", line 28, characters 0-43:
Warning: Declaring a scope implicitly is deprecated; use in advance an
explicit "Declare Scope function_scope.".
[undeclared-scope,deprecated-since-8.10,deprecated,default]
File "/tmp/tmp6dvl5_pq/HoTT/Limits/Pullback.v", line 29, characters 0-35:
Warning: Declaring a scope implicitly is deprecated; use in advance an
explicit "Declare Scope type_scope.".
[undeclared-scope,deprecated-since-8.10,deprecated,default]
File "/tmp/tmp6dvl5_pq/HoTT/Limits/Pullback.v", line 30, characters 0-37:
Warning: Declaring a scope implicitly is deprecated; use in advance an
explicit "Declare Scope equiv_scope.".
[undeclared-scope,deprecated-since-8.10,deprecated,default]
File "/tmp/tmp6dvl5_pq/HoTT/Limits/Pullback.v", line 31, characters 0-35:
Warning: Declaring a scope implicitly is deprecated; use in advance an
explicit "Declare Scope path_scope.".
[undeclared-scope,deprecated-since-8.10,deprecated,default]
File "/tmp/tmp6dvl5_pq/HoTT/Limits/Pullback.v", line 36, characters 0-54:
Warning:
Legacy loading plugin method has been removed from Rocq, and the `:` syntax is deprecated, and its first argument ignored; please remove "ltac_plugin:" from your Declare ML
[legacy-loading-removed,deprecated-since-9.0,deprecated,default]
File "/tmp/tmp6dvl5_pq/HoTT/Limits/Pullback.v", line 36, characters 0-54:
Warning: "coq-core" has been renamed to "rocq-runtime".
[coq-core-plugin,deprecated-since-9.0,deprecated,default]
File "/tmp/tmp6dvl5_pq/HoTT/Limits/Pullback.v", line 74, characters 0-8:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmp6dvl5_pq/HoTT/Limits/Pullback.v", line 88, characters 0-8:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmp6dvl5_pq/HoTT/Limits/Pullback.v", line 89, characters 0-8:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmp6dvl5_pq/HoTT/Limits/Pullback.v", line 94, characters 0-8:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmp6dvl5_pq/HoTT/Limits/Pullback.v", line 96, characters 0-8:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmp6dvl5_pq/HoTT/Limits/Pullback.v", line 159, characters 0-8:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmp6dvl5_pq/HoTT/Limits/Pullback.v", line 161, characters 0-8:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmp6dvl5_pq/HoTT/Limits/Pullback.v", line 225, characters 2-49:
Error: Use of "Context" outside sections behaves as "#[local] Parameter" or
"#[local] Axiom" followed by "Existing Instance" for typeclasses.
[context-outside-section,vernacular,default]


�[93mIntermediate code not saved.�[0m
Failed to do everything at once; trying one at a time.
Section removal unsuccessful.
No successful changes.

I will now attempt to remove empty sections

No empty sections to remove.

I will now attempt to remove the admit tactic header

Non-fatal error: Failed to remove admit tactic header and preserve the error.  
The new error was:
Deprecated environment variable COQCORELIB, use ROCQRUNTIMELIB instead.
Warning: Deprecated environment variable COQCORELIB,
use ROCQRUNTIMELIB instead.
[deprecated-coq-env-var,deprecated-since-9.0,deprecated,default]
File "/tmp/tmpj9ogz43a/HoTT/Limits/Pullback.v", line 31, characters 0-43:
Warning: Declaring a scope implicitly is deprecated; use in advance an
explicit "Declare Scope function_scope.".
[undeclared-scope,deprecated-since-8.10,deprecated,default]
File "/tmp/tmpj9ogz43a/HoTT/Limits/Pullback.v", line 32, characters 0-35:
Warning: Declaring a scope implicitly is deprecated; use in advance an
explicit "Declare Scope type_scope.".
[undeclared-scope,deprecated-since-8.10,deprecated,default]
File "/tmp/tmpj9ogz43a/HoTT/Limits/Pullback.v", line 33, characters 0-37:
Warning: Declaring a scope implicitly is deprecated; use in advance an
explicit "Declare Scope equiv_scope.".
[undeclared-scope,deprecated-since-8.10,deprecated,default]
File "/tmp/tmpj9ogz43a/HoTT/Limits/Pullback.v", line 34, characters 0-35:
Warning: Declaring a scope implicitly is deprecated; use in advance an
explicit "Declare Scope path_scope.".
[undeclared-scope,deprecated-since-8.10,deprecated,default]
File "/tmp/tmpj9ogz43a/HoTT/Limits/Pullback.v", line 39, characters 0-54:
Warning:
Legacy loading plugin method has been removed from Rocq, and the `:` syntax is deprecated, and its first argument ignored; please remove "ltac_plugin:" from your Declare ML
[legacy-loading-removed,deprecated-since-9.0,deprecated,default]
File "/tmp/tmpj9ogz43a/HoTT/Limits/Pullback.v", line 39, characters 0-54:
Warning: "coq-core" has been renamed to "rocq-runtime".
[coq-core-plugin,deprecated-since-9.0,deprecated,default]
File "/tmp/tmpj9ogz43a/HoTT/Limits/Pullback.v", line 77, characters 0-8:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpj9ogz43a/HoTT/Limits/Pullback.v", line 91, characters 0-8:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpj9ogz43a/HoTT/Limits/Pullback.v", line 92, characters 0-8:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpj9ogz43a/HoTT/Limits/Pullback.v", line 97, characters 0-8:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpj9ogz43a/HoTT/Limits/Pullback.v", line 99, characters 0-8:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpj9ogz43a/HoTT/Limits/Pullback.v", line 162, characters 0-8:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpj9ogz43a/HoTT/Limits/Pullback.v", line 164, characters 0-8:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpj9ogz43a/HoTT/Limits/Pullback.v", line 297, characters 0-8:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpj9ogz43a/HoTT/Limits/Pullback.v", line 306, characters 0-8:
Error:  (in proof equiv_sq_move_23): Attempt to save an incomplete proof
(the proof term is not complete because of given up (admitted) goals).
If this is really what you want to do, use Admitted in place of Qed.


�[93mChanged file not saved.�[0m

Now, I will attempt to strip repeated newlines and trailing spaces from this file...
�[92m
Succeeded in stripping newlines and spaces.�[0m

Completed second minimization pass.

If you have any comments on your experience of the minimizer, please share them in a reply (possibly tagging @JasonGross).
If you believe there's a bug in the bug minimizer, please report it on the bug minimizer issue tracker.


(newref,sch_type, ind, sch_sort)

let do_scheme ~register ?(force_mutual=false) env l =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

register is ignored, this causes HoTT to fail as #[warnings="unsupported-attributes",register=no] Scheme PathSquare_ind := Induction for PathSquare Sort Type. is registering the scheme when they don't want it registered.

@SkySkimmer
Copy link
Contributor

@coqbot ci minimize ci-fiat_parsers ci-metarocq

@coqbot-app
Copy link
Contributor

coqbot-app bot commented Nov 18, 2025

I am now running minimization at commit daa1773 on requested targets ci-fiat_parsers, ci-metarocq. I'll come back to you with the results once it's done.

@github-actions github-actions bot added the needs: rebase Should be rebased on the latest master to solve conflicts or have a newer CI run. label Nov 18, 2025
@coqbot-app
Copy link
Contributor

coqbot-app bot commented Nov 18, 2025

Minimization interrupted by timeout, being automatically continued. Partially Minimized File /home/runner/work/run-coq-bug-minimizer/run-coq-bug-minimizer/builds/coq/coq-failing/_build_ci/metarocq/erasure/theories/EWcbvEval.v in 5h 15m 7s (from ci-metarocq) (interrupted by timeout, being automatically continued) (full log on GitHub Actions - verbose log)
⭐ ⏱️ Partially Minimized Coq File (timeout) (truncated to first and last 32KiB; full 113KiB file on GitHub Actions Artifacts under bug.v)
(* -*- mode: coq; coq-prog-args: ("-emacs" "-q" "-w" "-deprecated-native-compiler-option" "-native-compiler" "no" "-coqlib" "/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq//" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/utils/theories" "MetaRocq.Utils" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/common/theories" "MetaRocq.Common" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/pcuic/theories" "MetaRocq.PCUIC" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/safechecker-plugin/theories" "MetaRocq.SafeCheckerPlugin" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/template-pcuic/theories" "MetaRocq.TemplatePCUIC" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/template-rocq/theories" "MetaRocq.Template" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/safechecker/theories" "MetaRocq.SafeChecker" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/erasure/theories" "MetaRocq.Erasure" "-Q" "/github/workspace/cwd" "Top" "-Q" "/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Equations" "Equations" "-Q" "/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Ltac2" "Ltac2" "-Q" "/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Stdlib" "Stdlib" "-I" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/template-rocq" "-top" "MetaRocq.Erasure.EWcbvEval") -*- *)
(* File reduced by coq-bug-minimizer from original input, then from 2155 lines to 516 lines, then from 530 lines to 1482 lines, then from 1487 lines to 517 lines, then from 531 lines to 1202 lines, then from 1208 lines to 611 lines, then from 625 lines to 1214 lines, then from 1217 lines to 672 lines, then from 686 lines to 1728 lines, then from 1733 lines to 780 lines, then from 794 lines to 1587 lines, then from 1593 lines to 789 lines, then from 803 lines to 1613 lines, then from 1619 lines to 845 lines, then from 859 lines to 1466 lines, then from 1469 lines to 945 lines, then from 959 lines to 1859 lines, then from 1865 lines to 1022 lines, then from 1036 lines to 3851 lines, then from 3850 lines to 2939 lines *)
(* coqc version 9.2+alpha compiled with OCaml 4.14.2
   coqtop version 9.2+alpha
   Expected coqc runtime on this file: 4.878 sec
   Expected coqc peak memory usage on this file: 748960.0 kb *)










Require MetaRocq.Common.Environment.
Require MetaRocq.Common.Universes.
Require MetaRocq.Common.BasicAst.
Require MetaRocq.Common.Kernames.
Require MetaRocq.Utils.MRFSets.
Require MetaRocq.Utils.utils.
Require MetaRocq.Utils.MRUtils.
Require MetaRocq.Utils.Show.
Require MetaRocq.Common.Primitive.
Require MetaRocq.Utils.MRMSets.
Require MetaRocq.Utils.MRString.
Require MetaRocq.Utils.monad_utils.
Require MetaRocq.Utils.All_Forall.
Require MetaRocq.Utils.MROption.
Require MetaRocq.Utils.MRList.
Require MetaRocq.Utils.MRReflect.
Require MetaRocq.Utils.MRPrelude.
Require MetaRocq.Utils.bytestring.
Require MetaRocq.Utils.ByteCompareSpec.
Require Stdlib.FSets.FMapFullAVL.
Require Stdlib.Strings.PString.
Require Stdlib.Numbers.Cyclic.Int63.Sint63.
Require Stdlib.Numbers.Cyclic.Int63.Ring63.
Require Stdlib.micromega.ZifyUint63.
Require Stdlib.Numbers.Cyclic.Int63.Cyclic63.
Require Stdlib.Numbers.Cyclic.Int63.Uint63.
Require Stdlib.FSets.FMapAVL.
Require Stdlib.Numbers.Cyclic.Abstract.CyclicAxioms.
Require MetaRocq.Utils.MRArith.
Require Stdlib.ZArith.ZArith.
Require Stdlib.ZArith.Zpow_facts.
Require Stdlib.ZArith.Zgcd_alt.
Require Stdlib.ZArith.Znumtheory.
Require MetaRocq.Common.config.
Require Stdlib.ZArith.ZNsatz.
Require Stdlib.ZArith.Zbitwise.
Require Stdlib.btauto.Btauto.
Require Stdlib.micromega.ZArith_hints.
Require Stdlib.btauto.Reflect.
Require Stdlib.btauto.Algebra.
Require Stdlib.ZArith.Zcong.
Require Stdlib.ZArith.ZModOffset.
Require Stdlib.ZArith.Zdivisibility.
Require Stdlib.ZArith.Zdiv_facts.
Require Stdlib.micromega.Lia.
Require Stdlib.MSets.MSetProperties.
Require Stdlib.MSets.MSetDecide.
Require Stdlib.MSets.MSetFacts.
Require Stdlib.FSets.FMapFacts.
Require Stdlib.micromega.ZMicromega.
Require Stdlib.Structures.DecidableTypeEx.
Require Stdlib.Structures.OrderedTypeEx.
Require Stdlib.ZArith.Zdiv.
Require Stdlib.ZArith.Zpower.
Require Stdlib.ZArith.Zcomplements.
Require Stdlib.Numbers.HexadecimalString.
Require Stdlib.Numbers.DecimalString.
Require Stdlib.MSets.MSetAVL.
Require MetaRocq.Utils.MRCompare.
Require Stdlib.omega.PreOmega.
Require Stdlib.micromega.ZifyBool.
Require Stdlib.MSets.MSetGenTree.
Require Stdlib.micromega.Zify.
Require Stdlib.Strings.String.
Require MetaRocq.Utils.ReflectEq.
Require Stdlib.micromega.ZifyInst.
Require Stdlib.ZArith.ZArith_base.
Require Stdlib.Arith.Arith.
Require Equations.Prop.Equations.
Require Stdlib.micromega.ZCoeff.
Require Stdlib.ZArith.Zhints.
Require Equations.Prop.Telescopes.
Require Equations.Prop.Loader.
Require Stdlib.NArith.NArith.
Require Equations.Prop.EqDecInstances.
Require Stdlib.nsatz.NsatzTactic.
Require Stdlib.micromega.RingMicromega.
Require Equations.Prop.NoConfusion.
Require Stdlib.ZArith.Zabs.
Require Stdlib.setoid_ring.Integral_domain.
Require Stdlib.ZArith.Zbool.
Require Stdlib.setoid_ring.ZArithRing.
Require Stdlib.setoid_ring.Cring.
Require Stdlib.setoid_ring.ArithRing.
Require Stdlib.ZArith.Wf_Z.
Require Stdlib.setoid_ring.NArithRing.
Require Stdlib.micromega.OrderedRing.
Require Stdlib.ZArith.ZArith_dec.
Require Stdlib.setoid_ring.Ring.
Require Stdlib.setoid_ring.Ncring_tac.
Require Stdlib.setoid_ring.Ring_base.
Require Stdlib.setoid_ring.Ncring_initial.
Require Stdlib.omega.OmegaLemmas.
Require Stdlib.ZArith.auxiliary.
Require Stdlib.ZArith.Zmisc.
Require Stdlib.ZArith.Zminmax.
Require Stdlib.ZArith.Zmin.
Require Stdlib.ZArith.Zmax.
Require Stdlib.setoid_ring.Ring_tac.
Require Stdlib.setoid_ring.Ncring_polynom.
Require Stdlib.ZArith.Zorder.
Require Stdlib.ZArith.Znat.
Require Stdlib.setoid_ring.InitialRing.
Require Stdlib.setoid_ring.Ring_polynom.
Require Stdlib.micromega.EnvRing.
Require Stdlib.micromega.VarMap.
Require Stdlib.micromega.Env.
Require Stdlib.Numbers.Cyclic.Abstract.DoubleType.
Require Stdlib.setoid_ring.Ncring.
Require Stdlib.ZArith.Zpow_def.
Require Equations.Prop.Tactics.
Require Stdlib.ZArith.Zeven.
Require Stdlib.ZArith.Zcompare.
Require Stdlib.ZArith.Int.
Require Stdlib.ZArith.BinInt.
Require Equations.Prop.Subterm.
Require Stdlib.NArith.Ndec.
Require Stdlib.Vectors.Bvector.
Require Stdlib.micromega.DeclConstantZ.
Require Stdlib.Strings.Ascii.
Require MetaRocq.Utils.ByteCompare.
Require Stdlib.Strings.Byte.
Require Stdlib.NArith.NArith_base.
Require Stdlib.Vectors.Vector.
Require Stdlib.Vectors.VectorEq.
Require Stdlib.ZArith.BinIntDef.
Require Stdlib.Vectors.VectorSpec.
Require Stdlib.Wellfounded.Wellfounded.
Require Stdlib.NArith.Nnat.
Require Stdlib.setoid_ring.Ring_theory.
Require Stdlib.NArith.Nsqrt_def.
Require Stdlib.NArith.Ngcd_def.
Require Stdlib.NArith.Ndiv_def.
Require Stdlib.MSets.MSetList.
Require Stdlib.setoid_ring.BinList.
Require Stdlib.NArith.BinNat.
Require Stdlib.Vectors.VectorDef.
Require Stdlib.PArith.PArith.
Require Stdlib.NArith.BinNatDef.
Require Stdlib.Vectors.Fin.
Require Stdlib.FSets.FMapList.
Require Stdlib.Structures.OrdersLists.
Require Stdlib.PArith.Pnat.
Require Stdlib.PArith.POrderedType.
Require Stdlib.FSets.FMapInterface.
Require Stdlib.Arith.Arith_base.
Require Stdlib.Structures.OrdersAlt.
Require Stdlib.Structures.OrderedTypeAlt.
Require Stdlib.Structures.EqualitiesFacts.
Require Stdlib.PArith.BinPos.
Require Stdlib.MSets.MSetInterface.
Require Stdlib.Wellfounded.Lexicographic_Exponentiation.
Require Stdlib.Structures.OrderedType.
Require Stdlib.Structures.DecidableType.
Require Stdlib.Sorting.SetoidList.
Require Stdlib.Lists.ListTactics.
Require Stdlib.micromega.Tauto.
Require Stdlib.Sorting.Sorted.
Require Stdlib.micromega.Refl.
Require Stdlib.Wellfounded.List_Extension.
Require Stdlib.Lists.List.
Require Stdlib.Arith.Peano_dec.
Require Stdlib.Arith.Wf_nat.
Require Stdlib.Arith.Factorial.
Require Stdlib.Arith.EqNat.
Require Stdlib.Arith.Compare_dec.
Require Stdlib.Arith.Between.
Require Stdlib.Arith.PeanoNat.
Require Stdlib.Numbers.Natural.Abstract.NProperties.
Require Stdlib.Numbers.Integer.Abstract.ZProperties.
Require Stdlib.Numbers.Natural.Abstract.NLcm0.
Require Stdlib.Numbers.Natural.Abstract.NBits.
Require Stdlib.Numbers.Integer.Abstract.ZLcm.
Require Stdlib.Numbers.Integer.Abstract.ZBits.
Require Stdlib.Numbers.Natural.Abstract.NLog.
Require Stdlib.Numbers.Natural.Abstract.NLcm.
Require Stdlib.Numbers.Integer.Abstract.ZPow.
Require Stdlib.Numbers.Natural.Abstract.NPow.
Require Stdlib.Numbers.Natural.Abstract.NDiv0.
Require Stdlib.Numbers.Integer.Abstract.ZGcd.
Require Stdlib.Numbers.Integer.Abstract.ZDivTrunc.
Require Stdlib.Numbers.Integer.Abstract.ZDivFloor.
Require Stdlib.Numbers.Natural.Abstract.NSqrt.
Require Stdlib.Numbers.Natural.Abstract.NParity.
Require Stdlib.Numbers.Natural.Abstract.NMaxMin.
Require Stdlib.Numbers.Natural.Abstract.NGcd.
Require Stdlib.Numbers.Natural.Abstract.NDiv.
Require Stdlib.Numbers.Integer.Abstract.ZSgnAbs.
Require Stdlib.Numbers.Integer.Abstract.ZParity.
Require Stdlib.Numbers.Integer.Abstract.ZMaxMin.
Require Stdlib.Numbers.Natural.Abstract.NSub.
Require Stdlib.Numbers.Integer.Abstract.ZMulOrder.
Require Stdlib.Numbers.Natural.Abstract.NMulOrder.
Require Stdlib.Numbers.Integer.Abstract.ZAddOrder.
Require Stdlib.Numbers.Natural.Abstract.NAddOrder.
Require Stdlib.Numbers.Integer.Abstract.ZLt.
Require Stdlib.Numbers.Natural.Abstract.NOrder.
Require Stdlib.Numbers.Integer.Abstract.ZMul.
Require Stdlib.Numbers.Natural.Abstract.NAdd.
Require Stdlib.Numbers.Integer.Abstract.ZAdd.
Require Stdlib.Numbers.Natural.Abstract.NBase.
Require Stdlib.Numbers.Integer.Abstract.ZBase.
Require Stdlib.Numbers.Natural.Abstract.NAxioms.
Require Stdlib.Numbers.Integer.Abstract.ZAxioms.
Require Stdlib.Numbers.NatInt.NZBits.
Require Stdlib.Numbers.NatInt.NZLog.
Require Stdlib.Numbers.NatInt.NZSqrt.
Require Stdlib.Numbers.NatInt.NZPow.
Require Stdlib.Numbers.NatInt.NZParity.
Require Stdlib.Numbers.NatInt.NZGcd.
Require Stdlib.Numbers.NatInt.NZDiv.
Require Stdlib.Numbers.NatInt.NZMulOrder.
Require Stdlib.Numbers.NatInt.NZAddOrder.
Require Stdlib.Numbers.NatInt.NZOrder.
Require Stdlib.Numbers.NatInt.NZMul.
Require Stdlib.Numbers.NatInt.NZAdd.
Require Stdlib.Numbers.NatInt.NZBase.
Require Stdlib.Numbers.NatInt.NZAxioms.
Require Stdlib.Program.Program.
Require Stdlib.Structures.GenericMinMax.
Require Stdlib.Structures.OrdersFacts.
Require Stdlib.Structures.OrdersTac.
Require Equations.Prop.Constants.
Require Stdlib.Structures.Orders.
Require Equations.Prop.FunctionalInduction.
Require Equations.Prop.DepElim.
Require MetaRocq.Utils.MRRelations.
Require Equations.Prop.EqDec.
Require Stdlib.Program.Subset.
Require Equations.Prop.Classes.
Require Stdlib.Structures.Equalities.
Require MetaRocq.Utils.MRProd.
Require Equations.Type.Relation_Properties.
Require Stdlib.Wellfounded.Lexicographic_Product.
Require Stdlib.Program.WfExtensionality.
Require Stdlib.Classes.RelationPairs.
Require MetaRocq.Utils.MRTactics.SpecializeUnderBindersBy.
Require MetaRocq.Utils.MRTactics.InHypUnderBindersDo.
Require Equations.Type.Relation.
Require Equations.Prop.Logic.
Require Stdlib.Numbers.NumPrelude.
Require Equations.Type.Logic.
Require Stdlib.Program.Equality.
Require Ltac2.Ltac1.
Require Stdlib.Wellfounded.Union.
Require Stdlib.Relations.Relations.
Require Stdlib.PArith.BinPosDef.
Require Equations.CoreTactics.
Require Stdlib.Wellfounded.Transitive_Closure.
Require Stdlib.Wellfounded.Disjoint_Union.
Require Stdlib.Relations.Operators_Properties.
Require Stdlib.Program.Combinators.
Require MetaRocq.Utils.MRTactics.GeneralizeOverHoles.
Require Ltac2.Control.
Require Equations.Signature.
Require Equations.Prop.SigmaNotations.
Require Stdlib.Wellfounded.Inclusion.
Require Stdlib.Relations.Relation_Operators.
Require Stdlib.Logic.ProofIrrelevance.
Require Stdlib.Logic.JMeq.
Require Stdlib.Bool.Bool.
Require MetaRocq.Utils.MRTactics.SpecializeAllWays.
Require MetaRocq.Utils.MRTactics.DestructHead.
Require Ltac2.Std.
Require Ltac2.Message.
Require Equations.Init.
Require Stdlib.ssr.ssreflect.
Require Stdlib.ssr.ssrfun.
Require Stdlib.ssr.ssrbool.
Require Stdlib.extraction.Extraction.
Require Stdlib.Wellfounded.Well_Ordering.
Require Stdlib.Unicode.Utf8.
Require Stdlib.Strings.PrimStringAxioms.
Require Stdlib.Strings.PrimString.
Require Stdlib.Setoids.Setoid.
Require Stdlib.Relations.Relation_Definitions.
Require Stdlib.Program.Wf.
Require Stdlib.Program.Utils.
Require Stdlib.Program.Tactics.
Require Stdlib.Program.Basics.
Require Stdlib.Numbers.Cyclic.Int63.Uint63Axioms.
Require Stdlib.Numbers.Cyclic.Int63.Sint63Axioms.
Require Stdlib.Numbers.Cyclic.Int63.PrimInt63.
Require Stdlib.Numbers.Cyclic.Int63.CarryType.
Require Stdlib.Numbers.BinNums.
Require Stdlib.Logic.ProofIrrelevanceFacts.
Require Stdlib.Logic.Eqdep_dec.
Require Stdlib.Logic.Eqdep.
Require Stdlib.Lists.ListDef.
Require Stdlib.Init.Sumbool.
Require Stdlib.Init.Nat.
Require Stdlib.Init.Byte.
Require Stdlib.Init.Decimal.
Require Stdlib.Init.Wf.
Require Stdlib.Init.Hexadecimal.
Require Stdlib.Floats.FloatOps.
Require Stdlib.Floats.SpecFloat.
Require Stdlib.Floats.PrimFloat.
Require Stdlib.Classes.RelationClasses.
Require Stdlib.Classes.Morphisms_Prop.
Require Stdlib.Classes.Morphisms.
Require Stdlib.Classes.CRelationClasses.
Require Stdlib.Classes.CMorphisms.
Require Stdlib.BinNums.IntDef.
Require Stdlib.BinNums.PosDef.
Require Stdlib.BinNums.NatDef.
Require MetaRocq.Utils.MRTactics.UniquePose.
Require Ltac2.Init.
Require Stdlib.setoid_ring.Algebra_syntax.
Require Stdlib.micromega.ZifyClasses.
Require Stdlib.Wellfounded.Inverse_Image.
Require Stdlib.Unicode.Utf8_core.
Require Stdlib.Sets.Relations_1.
Require Stdlib.Program.Syntax.
Require Stdlib.Logic.HLevelsBase.
Require Stdlib.Logic.FunctionalExtensionality.
Require Stdlib.Logic.EqdepFacts.
Require Stdlib.Logic.Decidable.
Require Stdlib.Classes.DecidableClass.
Require MetaRocq.Utils.MRTactics.Zeta1.
Require MetaRocq.Utils.MRTactics.SplitInContext.
Require MetaRocq.Utils.MRTactics.SpecializeBy.
Require MetaRocq.Utils.MRTactics.Head.
Require MetaRocq.Utils.MRTactics.FindHyp.
Require MetaRocq.Utils.MRTactics.DestructHyps.
Require MetaRocq.Utils.MRSquash.
Require MetaRocq.Utils.MREquality.
Require Corelib.extraction.Extraction.
Require Corelib.Numbers.BinNums.
Require Corelib.Strings.PrimStringAxioms.
Require Corelib.Classes.Morphisms.
Require Corelib.Classes.CMorphisms.
Require Corelib.Init.Sumbool.
Require Corelib.Strings.PrimString.
Require Corelib.Program.Wf.
Require Corelib.Classes.Morphisms_Prop.
Require Corelib.Init.Ltac.
Require Corelib.Program.Tactics.
Require Corelib.Program.Utils.
Require Corelib.Classes.RelationClasses.
Require Corelib.Lists.ListDef.
Require Corelib.ssr.ssrfun.
Require Corelib.Init.Byte.
Require Corelib.BinNums.NatDef.
Require Corelib.Init.Nat.
Require Corelib.ssr.ssreflect.
Require Corelib.BinNums.PosDef.
Require Corelib.Init.Decimal.
Require Corelib.Numbers.Cyclic.Int63.PrimInt63.
Require Corelib.ssr.ssrbool.
Require Corelib.Floats.PrimFloat.
Require Corelib.Classes.CRelationClasses.
Require Corelib.Relations.Relation_Definitions.
Require Corelib.Setoids.Setoid.
Require Corelib.Program.Basics.
Require Corelib.Numbers.Cyclic.Int63.Sint63Axioms.
Require Corelib.Init.Wf.
Require Corelib.Numbers.Cyclic.Int63.CarryType.
Require Corelib.BinNums.IntDef.
Require Corelib.Init.Hexadecimal.
Require Corelib.Floats.FloatOps.
Require Corelib.Numbers.Cyclic.Int63.Uint63Axioms.

Module Export AdmitTactic.
Module Import LocalFalse.
Inductive False : Prop := .
End LocalFalse.
Axiom proof_admitted : False.
Import Coq.Init.Ltac.
Tactic Notation "admit" := abstract case proof_admitted.
End AdmitTactic.

Module Export MetaRocq_DOT_Common_DOT_EnvironmentTyping_WRAPPED.
Module Export EnvironmentTyping.
Import Stdlib.ssr.ssreflect.
Import Stdlib.ssr.ssrbool.
Import MetaRocq.Utils.utils.
Import MetaRocq.Common.config.
Import MetaRocq.Common.BasicAst.
Import MetaRocq.Common.Universes.
Import MetaRocq.Common.Environment.
Import MetaRocq.Common.Primitive.
Import Equations.Prop.Equations.

Module Lookup (T : Term) (E : EnvironmentSig T).
Import T.
Import E.

  

  Definition declared_constant_gen (lookup : kername -> option global_decl) (id : kername) decl : Prop :=
    lookup id = Some (ConstantDecl decl).

  Definition declared_constant (Σ : global_env) id decl := In (id,ConstantDecl decl) (declarations Σ).

  Definition declared_minductive_gen (lookup : kername -> option global_decl) mind decl :=
    lookup mind = Some (InductiveDecl decl).

  Definition declared_minductive Σ mind decl := In (mind,InductiveDecl decl) (declarations Σ).

  Definition declared_inductive_gen lookup ind mdecl decl :=
    declared_minductive_gen lookup (inductive_mind ind) mdecl /\
    List.nth_error mdecl.(ind_bodies) (inductive_ind ind) = Some decl.

  Definition declared_inductive Σ ind mdecl decl :=
    declared_minductive Σ (inductive_mind ind) mdecl /\
    List.nth_error mdecl.(ind_bodies) (inductive_ind ind) = Some decl.

  Definition declared_constructor_gen lookup cstr mdecl idecl cdecl : Prop :=
    declared_inductive_gen lookup (fst cstr) mdecl idecl /\
    List.nth_error idecl.(ind_ctors) (snd cstr) = Some cdecl.

  Definition declared_constructor Σ cstr mdecl idecl cdecl :=
    declared_inductive Σ (fst cstr) mdecl idecl /\
    List.nth_error idecl.(ind_ctors) (snd cstr) = Some cdecl.

  Definition declared_projection_gen lookup (proj : projection) mdecl idecl cdecl pdecl
  : Prop :=
    declared_constructor_gen lookup (proj.(proj_ind), 0) mdecl idecl cdecl /\
    List.nth_error idecl.(ind_projs) proj.(proj_arg) = Some pdecl /\
    mdecl.(ind_npars) = proj.(proj_npars).

  Definition declared_projection Σ (proj : projection) mdecl idecl cdecl pdecl
  : Prop :=
    declared_constructor Σ (proj.(proj_ind), 0) mdecl idecl cdecl /\
    List.nth_error idecl.(ind_projs) proj.(proj_arg) = Some pdecl /\
    mdecl.(ind_npars) = proj.(proj_npars).

  Definition lookup_constant_gen (lookup : kername -> option global_decl) kn :=
    match lookup kn with
    | Some (ConstantDecl d) => Some d
    | _ => None
    end.

  Definition lookup_constant Σ := lookup_constant_gen (lookup_env Σ).

  Definition lookup_minductive_gen (lookup : kername -> option global_decl) mind :=
    match lookup mind with
    | Some (InductiveDecl decl) => Some decl
    | _ => None
    end.

  Definition lookup_minductive Σ := lookup_minductive_gen (lookup_env Σ).

  Definition lookup_inductive_gen lookup ind :=
    match lookup_minductive_gen lookup (inductive_mind ind) with
    | Some mdecl =>
      match nth_error mdecl.(ind_bodies) (inductive_ind ind) with
      | Some idecl => Some (mdecl, idecl)
      | None => None
      end
    | None => None
    end.

  Definition lookup_inductive Σ := lookup_inductive_gen (lookup_env Σ).

  Definition lookup_constructor_gen lookup ind k :=
    match lookup_inductive_gen lookup ind with
    | Some (mdecl, idecl) =>
      match nth_error idecl.(ind_ctors) k with
      | Some cdecl => Some (mdecl, idecl, cdecl)
      | None => None
      end
    | _ => None
    end.

  Definition lookup_constructor Σ := lookup_constructor_gen (lookup_env Σ).

  Definition lookup_projection_gen lookup p :=
    match lookup_constructor_gen lookup p.(proj_ind) 0 with
    | Some (mdecl, idecl, cdecl) =>
      match nth_error idecl.(ind_projs) p.(proj_arg) with
      | Some pdecl => Some (mdecl, idecl, cdecl, pdecl)
      | None => None
      end
    | _ => None
    end.

  Definition lookup_projection Σ := lookup_projection_gen (lookup_env Σ).

  Lemma declared_constant_lookup_gen {lookup kn cdecl} :
    declared_constant_gen lookup kn cdecl ->
    lookup_constant_gen lookup kn = Some cdecl.
Admitted.

  Lemma lookup_constant_declared_gen {lookup kn cdecl} :
    lookup_constant_gen lookup kn = Some cdecl ->
    declared_constant_gen lookup kn cdecl.
Admitted.

  Lemma declared_minductive_lookup_gen {lookup ind mdecl} :
    declared_minductive_gen lookup ind mdecl ->
    lookup_minductive_gen lookup ind = Some mdecl.
Admitted.

  Lemma lookup_minductive_declared_gen {lookup ind mdecl} :
    lookup_minductive_gen lookup ind = Some mdecl ->
    declared_minductive_gen lookup ind mdecl.
Admitted.

  Lemma declared_inductive_lookup_gen {lookup ind mdecl idecl} :
    declared_inductive_gen lookup ind mdecl idecl ->
    lookup_inductive_gen lookup ind = Some (mdecl, idecl).
Admitted.

  Lemma lookup_inductive_declared_gen {lookup ind mdecl idecl} :
    lookup_inductive_gen lookup ind = Some (mdecl, idecl) ->
    declared_inductive_gen lookup ind mdecl idecl.
Admitted.

  Lemma declared_constructor_lookup_gen {lookup id mdecl idecl cdecl} :
    declared_constructor_gen lookup id mdecl idecl cdecl ->
    lookup_constructor_gen lookup id.1 id.2 = Some (mdecl, idecl, cdecl).
Admitted.

  Lemma lookup_constructor_declared_gen {lookup id mdecl idecl cdecl} :
    lookup_constructor_gen lookup id.1 id.2 = Some (mdecl, idecl, cdecl) ->
    declared_constructor_gen lookup id mdecl idecl cdecl.
Admitted.

  Lemma declared_projection_lookup_gen {lookup p mdecl idecl cdecl pdecl} :
    declared_projection_gen lookup p mdecl idecl cdecl pdecl ->
    lookup_projection_gen lookup p = Some (mdecl, idecl, cdecl, pdecl).
Admitted.

  Lemma lookup_projection_declared_gen {lookup p mdecl idecl cdecl pdecl} :
    ind_npars mdecl = p.(proj_npars) ->
    lookup_projection_gen lookup p = Some (mdecl, idecl, cdecl, pdecl) ->
    declared_projection_gen lookup p mdecl idecl cdecl pdecl.
Admitted.

  Definition on_udecl_decl {A} (F : universes_decl -> A) d : A :=
  match d with
  | ConstantDecl cb => F cb.(cst_universes)
  | InductiveDecl mb => F mb.(ind_universes)
  end.

  Definition universes_decl_of_decl := on_udecl_decl (fun x => x).
Definition global_levels (univs : ContextSet.t) : LevelSet.t. exact (LevelSet.union (ContextSet.levels univs) (LevelSet.singleton (Level.lzero))). Defined.

  Lemma global_levels_InSet Σ :
    LevelSet.In Level.lzero (global_levels Σ).
Admitted.

  Lemma global_levels_memSet univs :
    LevelSet.mem Level.lzero (global_levels univs) = true.
Admitted.
Definition global_constraints (Σ : global_env) : ConstraintSet.t. exact (snd Σ.(universes)). Defined.
Definition global_uctx (Σ : global_env) : ContextSet.t. exact ((global_levels Σ.(universes), global_constraints Σ)). Defined.
Definition global_ext_levels (Σ : global_env_ext) : LevelSet.t. exact (LevelSet.union (levels_of_udecl (snd Σ)) (global_levels Σ.1.(universes))). Defined.
Definition global_ext_constraints (Σ : global_env_ext) : ConstraintSet.t. exact (ConstraintSet.union
      (constraints_of_udecl (snd Σ))
      (global_constraints Σ.1)). Defined.

  Coercion global_ext_constraints : global_env_ext >-> ConstraintSet.t.
Definition global_ext_uctx (Σ : global_env_ext) : ContextSet.t. exact ((global_ext_levels Σ, global_ext_constraints Σ)). Defined.

  Lemma global_ext_levels_InSet Σ :
    LevelSet.In Level.lzero (global_ext_levels Σ).
Admitted.

  

  Definition consistent_instance `{checker_flags} (lvs : LevelSet.t) (φ : ConstraintSet.t) uctx (u : Instance.t) :=
    match uctx with
    | Monomorphic_ctx => List.length u = 0
    | Polymorphic_ctx c =>
      
      forallb (fun l => LevelSet.mem l lvs) u /\
      List.length u = List.length c.1 /\
      valid_constraints φ (subst_instance_cstrs u c.2)
    end.

  Definition consistent_instance_ext `{checker_flags} Σ :=
    consistent_instance (global_ext_levels Σ) (global_ext_constraints Σ).

  Lemma consistent_instance_length {cf : checker_flags} {Σ : global_env_ext} {univs u} :
    consistent_instance_ext Σ univs u ->
    #|u| = #|abstract_instance univs|.
Admitted.

  Definition wf_universe Σ (u : Universe.t) : Prop :=
    forall l, LevelExprSet.In l u -> LevelSet.In (LevelExpr.get_level l) (global_ext_levels Σ).

  Definition wf_sort Σ (s : sort) : Prop :=
    Sort.on_sort (wf_universe Σ) True s.

  Definition wf_universe_dec Σ u : {wf_universe Σ u} + {~wf_universe Σ u}.
Admitted.

  Definition wf_sort_dec Σ s : {@wf_sort Σ s} + {~@wf_sort Σ s}.
Admitted.

  Lemma declared_ind_declared_constructors `{cf : checker_flags} {Σ ind mib oib} :
    declared_inductive Σ ind mib oib ->
    Alli (fun i => declared_constructor Σ (ind, i) mib oib) 0 (ind_ctors oib).
Admitted.

End Lookup.

Module Type LookupSig (T : Term) (E : EnvironmentSig T).
  Include Lookup T E.
End LookupSig.

Module EnvTyping (T : Term) (E : EnvironmentSig T) (TU : TermUtils T E).
Import T.
Import E.
Import TU.

  

  Notation on_local_decl P Γ d :=
    (P Γ (j_decl d)) (only parsing).

  Definition on_def_type (P : context -> judgment -> Type) Γ d :=
    P Γ (TypRel d.(dtype) d.(dname).(binder_relevance)).

  Definition on_def_body (P : context -> judgment -> Type) types Γ d :=
    P (Γ ,,, types) (TermTypRel d.(dbody) (lift0 #|types| d.(dtype)) d.(dname).(binder_relevance)).

  

  Definition lift_wf_term wf_term (j : judgment) := option_default wf_term (j_term j) (unit : Type) × wf_term (j_typ j).
  Notation lift_wf_term1 wf_term := (fun (Γ : context) => lift_wf_term (wf_term Γ)).

  Definition lift_wfu_term wf_term wf_univ (j : judgment) := option_default wf_term (j_term j) (unit : Type) × wf_term (j_typ j) × option_default wf_univ (j_univ j) (unit : Type).

  Definition lift_wfb_term wfb_term (j : judgment) := option_default wfb_term (j_term j) true && wfb_term (j_typ j).
  Notation lift_wfb_term1 wfb_term := (fun (Γ : context) => lift_wfb_term (wfb_term Γ)).

  Definition lift_wfbu_term wfb_term wfb_univ (j : judgment) := option_default wfb_term (j_term j) true && wfb_term (j_typ j) && option_default wfb_univ (j_univ j) true.

  Definition lift_sorting checking sorting : judgment -> Type :=
    fun j => option_default (fun tm => checking tm (j_typ j)) (j_term j) (unit : Type) ×
                                ∑ s, sorting (j_typ j) s ×
                                  option_default (fun u => u = s) (j_univ j) True /\
                                  isSortRelOpt s (j_rel j).

  Notation lift_sorting1 checking sorting := (fun Γ => lift_sorting (checking Γ) (sorting Γ)).
  Notation lift_sorting2 checking sorting := (fun Σ Γ => lift_sorting (checking Σ Γ) (sorting Σ Γ)).

  Notation typing_sort typing := (fun T s => typing T (tSort s)).
  Notation typing_sort1 typing := (fun Γ T s => typing Γ T (tSort s)).
  Notation typing_sort2 typing := (fun Σ Γ T s => typing Σ Γ T (tSort s)).

  Definition lift_typing0 typing := lift_sorting typing (typing_sort typing).
  Notation lift_typing1 typing := (fun Γ => lift_typing0 (typing Γ)).
  Notation lift_typing typing := (fun Σ Γ => lift_typing0 (typing Σ Γ)).

  Notation Prop_local_conj P Q := (fun Γ t T => P Γ t T × Q Γ t T).
  Notation Prop_conj P Q := (fun Σ Γ t T => P Σ Γ t T × Q Σ Γ t T).

  Definition lift_typing_conj (P Q : context -> _) := lift_typing1 (Prop_local_conj P Q).

  Lemma lift_wf_term_it_impl {P Q} {tm tm' : option term} {t t' : term} {u u' r r'} :
    forall tu: lift_wf_term P (Judge tm t u r),
    match tm', tm with None, _ => unit | Some tm', Some tm => P tm -> Q tm' | _, _ => False end ->
    (P t -> Q t') ->
    lift_wf_term Q (Judge tm' t' u' r').
Admitted.

  Lemma lift_wf_term_f_impl P Q tm t u u' r r' :
    forall f,
    lift_wf_term P (Judge tm t u r) ->
    (forall t, P t -> Q (f t)) ->
    lift_wf_term Q (Judge (option_map f tm) (f t) u' r').
Admitted.

  Lemma lift_wf_term_impl P Q j :
    lift_wf_term P j ->
    (forall t, P t -> Q t) ->
    lift_wf_term Q j.
Admitted.

  Lemma lift_wfbu_term_f_impl (P Q : term -> bool) tm t u r :
    forall f fu,
    lift_wfbu_term P (P ∘ tSort) (Judge tm t u r) ->
    (forall u, f (tSort u) = tSort (fu u)) ->
    (forall t, P t -> Q (f t)) ->
    lift_wfbu_term Q (Q ∘ tSort) (Judge (option_map f tm) (f t) (option_map fu u) r).
Admitted.

  Lemma lift_wf_wfb_term (p : _ -> bool) j :
    reflectT (lift_wf_term p j) (lift_wfb_term p j).
Admitted.

  Lemma lift_wfu_wfbu_term (p : _ -> bool) (pu : _ -> bool) j :
    reflectT (lift_wfu_term p pu j) (lift_wfbu_term p pu j).
Admitted.

  Lemma unlift_TermTyp {Pc Ps tm ty u r} :
    lift_sorting Pc Ps (Judge (Some tm) ty u r) ->
    Pc tm ty.
Admitted.
Definition unlift_TypUniv {Pc Ps tm ty u r} :
    lift_sorting Pc Ps (Judge tm ty (Some u) r) ->
    Ps ty u. exact (fun H => eq_rect_r _ H.2.π2.1 H.2.π2.2.p1). Defined.
Definition lift_sorting_extract {c s tm ty r} (w : lift_sorting c s (Judge tm ty None r)) :
    lift_sorting c s (Judge tm ty (Some w.2.π1) r). exact ((w.1, (w.2.π1; (w.2.π2.1, (conj eq_refl w.2.π2.2.p2))))). Defined.

  Lemma lift_sorting_forget_univ {Pc Ps tm ty u r} :
    lift_sorting Pc Ps (Judge tm ty u r) ->
    lift_sorting Pc Ps (Judge tm ty None r).
Admitted.

  Lemma lift_sorting_forget_body {Pc Ps tm ty u r} :
    lift_sorting Pc Ps (Judge tm ty u r) ->
    lift_sorting Pc Ps (Judge None ty u r).
Admitted.

  Lemma lift_sorting_forget_rel {Pc Ps tm ty u r} :
    lift_sorting Pc Ps (Judge tm ty u r) ->
    lift_sorting Pc Ps (Judge tm ty u None).
Admitted.

  Lemma lift_sorting_ex_it_impl_gen {Pc Qc Ps Qs} {tm tm' : option term} {t t' : term} {r r' : option relevance} :
    forall tu: lift_sorting Pc Ps (Judge tm t None r),
    let s := tu.2.π1 in
    match tm', tm with None, _ => unit | Some tm', Some tm => Pc tm t -> Qc tm' t' | _, _ => False end ->
    (Ps t s -> isSortRelOpt s r -> ∑ s', Qs t' s' × isSortRelOpt s' r') ->
    lift_sorting Qc Qs (Judge tm' t' None r').
Admitted.

  Lemma lift_sorting_it_impl_gen {Pc Qc Ps Qs} {tm tm' : option term} {t t' : term} {u r} :
    forall tu: lift_sorting Pc Ps (Judge tm t u r),
    let s := tu.2.π1 in
    match tm', tm with None, _ => unit | Some tm', Some tm => Pc tm t -> Qc tm' t' | _, _ => False end ->
    (Ps t s -> Qs t' s) ->
    lift_sorting Qc Qs (Judge tm' t' u r).
Admitted.

  Lemma lift_sorting_fu_it_impl {Pc Qc Ps Qs} {tm : option term} {t : term} {u r} :
    forall f fu, forall tu: lift_sorting Pc Ps (Judge tm t u r),
    let s := tu.2.π1 in
    option_default (fun rel => isSortRel s rel -> isSortRel (fu s) rel) r True ->
    option_default (fun tm => Pc tm t -> Qc (f tm) (f t)) tm unit ->
    (Ps t s -> Qs (f t) (fu s)) ->
    lift_sorting Qc Qs (Judge (option_map f tm) (f t) (option_map fu u) r).
Admitted.

  Lemma lift_sorting_f_it_impl {Pc Qc Ps Qs} {j : judgment} :
    forall f, forall tu: lift_sorting Pc Ps j,
    let s := tu.2.π1 in
    option_default (fun tm => Pc tm (j_typ j) -> Qc (f tm) (f (j_typ j))) (j_term j) unit ->
    (Ps (j_typ j) s -> Qs (f (j_typ j)) s) ->
    lift_sorting Qc Qs (judgment_map f j).
Admitted.

  Lemma lift_sorting_it_impl {Pc Qc Ps Qs} {j} :
    forall tu: lift_sorting Pc Ps j,
    let s := tu.2.π1 in
    option_default (fun tm => Pc tm (j_typ j) -> Qc tm (j_typ j)) (j_term j) unit ->
    (Ps (j_typ j) s -> Qs (j_typ j) s) ->
    lift_sorting Qc Qs j.
Admitted.

  Lemma lift_sorting_fu_impl {Pc Qc Ps Qs tm t u r} :
    forall f fu,
    lift_sorting Pc Ps (Judge tm t u r) ->
    (forall r s, isSortRelOpt s r -> isSortRelOpt (fu s) r) ->
    (forall t T, Pc t T -> Qc (f t) (f T)) ->
    (forall t u, Ps t u -> Qs (f t) (fu u)) ->
    lift_sorting Qc Qs (Judge (option_map f tm) (f t) (option_map fu u) r).
Admitted.

  Lemma lift_typing_fu_impl {P Q tm t u r} :
    forall f fu,
    lift_typing0 P (Judge tm t u r) ->
    (forall t T, P t T -> Q (f t) (f T)) ->
    (forall u, f (tSort u) = tSort (fu u)) ->
    (forall r s, isSortRelOpt s r -> isSortRelOpt (fu s) r) ->
    lift_typing0 Q (Judge (option_map f tm) (f t) (option_map fu u) r).
Admitted.

  Lemma lift_sorting_f_impl {Pc Qc Ps Qs j} :
    forall f,
    lift_sorting Pc Ps j ->
    (forall t T, Pc t T -> Qc (f t) (f T)) ->
    (forall t u, Ps t u -> Qs (f t) u) ->
    lift_sorting Qc Qs (judgment_map f j).
Admitted.

  Lemma lift_typing_f_impl {P Q j} :
    forall f,
    lift_typing0 P j ->
    (forall t T, P t T -> Q (f t) (f T)) ->
    (forall u, f (tSort u) = tSort u) ->
    lift_typing0 Q (judgment_map f j).
Admitted.

  Lemma lift_typing_map {P} f j :
    lift_typing0 (fun t T => P (f t) (f T)) j ->
    (forall u, f (tSort u) = tSort u) ->
    lift_typing0 P (judgment_map f j).
Admitted.

  Lemma lift_typing_mapu {P} f fu {tm ty u r} :
    lift_typing0 (fun t T => P (f t) (f T)) (Judge tm ty u r) ->
    (forall u, f (tSort u) = tSort (fu u)) ->
    (forall r s, isSortRelOpt s r -> isSortRelOpt (fu s) r) ->
    lift_typing0 P (Judge (option_map f tm) (f ty) (option_map fu u) r).
Admitted.

  Lemma lift_sorting_i

[...]


  | tPrim _ => true
  | _ => false
  end.

Definition isBox t :=
  match t with
  | tBox => true
  | _ => false
  end.

Definition isLazy c :=
  match c with
  | tLazy _ => true
  | _ => false
  end.

Definition isFixApp t := isFix (head t).
Definition isConstructApp t := isConstruct (head t).
Definition isPrimApp t := isPrim (head t).
Definition isLazyApp t := isLazy (head t).

Section PrimDeps.

End PrimDeps.
Module Export MetaRocq.
Module Export Erasure.
Module Export EAstUtils.
End EAstUtils.

Section All_rec.
End All_rec.
Section MkApps_rec.

  End MkApps_rec.

  Section MkApps_case.

  End MkApps_case.
Module Export ELiftSubst.

Import MetaRocq.Utils.utils.
Import MetaRocq.Erasure.EPrimitive.
Import MetaRocq.Erasure.EAst.

Fixpoint lift n k t : term :=
  match t with
  | tRel i => if Nat.leb k i then tRel (n + i) else tRel i
  | tEvar ev args => tEvar ev (List.map (lift n k) args)
  | tLambda na M => tLambda na (lift n (S k) M)
  | tApp u v => tApp (lift n k u) (lift n k v)
  | tLetIn na b b' => tLetIn na (lift n k b) (lift n (S k) b')
  | tCase ind c brs =>
    let brs' := List.map (fun br =>
      (br.1, lift n (#|br.1| + k) br.2)) brs in
    tCase ind (lift n k c) brs'
  | tProj p c => tProj p (lift n k c)
  | tFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (lift n k')) mfix in
    tFix mfix' idx
  | tCoFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (lift n k')) mfix in
    tCoFix mfix' idx
  | tBox => t
  | tVar _ => t
  | tConst _ => t
  | tConstruct ind i args => tConstruct ind i (map (lift n k) args)
  | tPrim p => tPrim (map_prim (lift n k) p)
  | tLazy t => tLazy (lift n k t)
  | tForce t => tForce (lift n k t)
  end.

Notation lift0 n := (lift n 0).

Fixpoint subst s k u :=
  match u with
  | tRel n =>
    if Nat.leb k n then
      match nth_error s (n - k) with
      | Some b => lift0 k b
      | None => tRel (n - List.length s)
      end
    else tRel n
  | tEvar ev args => tEvar ev (List.map (subst s k) args)
  | tLambda na M => tLambda na (subst s (S k) M)
  | tApp u v => tApp (subst s k u) (subst s k v)
  | tLetIn na b b' => tLetIn na (subst s k b) (subst s (S k) b')
  | tCase ind c brs =>
    let brs' := List.map (fun br => (br.1, subst s (#|br.1| + k) br.2)) brs in
    tCase ind (subst s k c) brs'
  | tProj p c => tProj p (subst s k c)
  | tFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (subst s k')) mfix in
    tFix mfix' idx
  | tCoFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (subst s k')) mfix in
    tCoFix mfix' idx
  | tConstruct ind i args => tConstruct ind i (map (subst s k) args)
  | tPrim p => tPrim (map_prim (subst s k) p)
  | tLazy t => tLazy (subst s k t)
  | tForce t => tForce (subst s k t)
  | tBox => tBox
  | tVar n => tVar n
  | tConst c => tConst c
  end.

Notation subst0 t := (subst t 0).

Fixpoint closedn k (t : term) : bool :=
  match t with
  | tRel i => Nat.ltb i k
  | tEvar ev args => List.forallb (closedn k) args
  | tLambda _ M => closedn (S k) M
  | tApp u v => closedn k u && closedn k v
  | tLetIn na b b' => closedn k b && closedn (S k) b'
  | tCase ind c brs =>
    let brs' := List.forallb (fun br => closedn (#|br.1| + k) br.2) brs in
    closedn k c && brs'
  | tProj p c => closedn k c
  | tFix mfix idx =>
    let k' := List.length mfix + k in
    List.forallb (test_def (closedn k')) mfix
  | tCoFix mfix idx =>
    let k' := List.length mfix + k in
    List.forallb (test_def (closedn k')) mfix
  | tConstruct ind i args => forallb (closedn k) args
  | tPrim p => test_prim (closedn k) p
  | tLazy t => closedn k t
  | tForce t => closedn k t
  | _ => true
  end.

Notation closed t := (closedn 0 t).

Set SsrRewrite.

Lemma closedn_subst s k t :
  forallb (closedn k) s -> closedn (#|s| + k) t ->
  closedn k (subst0 s t).
Admitted.
Module Export MetaRocq.
Module Export Erasure.
Module Export ELiftSubst.
End ELiftSubst.
Module Export ECSubst.
Import MetaRocq.Utils.utils.
Import MetaRocq.Erasure.EPrimitive.
Import MetaRocq.Erasure.EAst.

Fixpoint csubst t k u :=
  match u with
  | tBox => tBox
  | tRel n =>
     match Nat.compare k n with
    | Datatypes.Eq => t
    | Gt => tRel n
    | Lt => tRel (Nat.pred n)
    end
  | tEvar ev args => tEvar ev (List.map (csubst t k) args)
  | tLambda na M => tLambda na (csubst t (S k) M)
  | tApp u v => tApp (csubst t k u) (csubst t k v)
  | tLetIn na b b' => tLetIn na (csubst t k b) (csubst t (S k) b')
  | tCase ind c brs =>
    let brs' := List.map (fun br => (br.1, csubst t (#|br.1| + k) br.2)) brs in
    tCase ind (csubst t k c) brs'
  | tProj p c => tProj p (csubst t k c)
  | tFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (csubst t k')) mfix in
    tFix mfix' idx
  | tCoFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (csubst t k')) mfix in
    tCoFix mfix' idx
  | tConstruct ind n args => tConstruct ind n (map (csubst t k) args)
  | tPrim p => tPrim (map_prim (csubst t k) p)
  | tLazy u => tLazy (csubst t k u)
  | tForce u => tForce (csubst t k u)
  | x => x
  end.

Definition substl defs body : term :=
  fold_left (fun bod term => csubst term 0 bod)
    defs body.

Lemma closed_subst t k u : closed t ->
    csubst t k u = subst [t] k u.
Admitted.

Lemma closed_substl ts k u :
  forallb (closedn 0) ts ->
  closedn (#|ts| + k) u ->
  closedn k (ECSubst.substl ts u).
Admitted.
Module Export MetaRocq_DOT_Erasure_DOT_ECSubst.
Module Export MetaRocq.
Module Export Erasure.
Module Export ECSubst.
End ECSubst.

End Erasure.

End MetaRocq.

End MetaRocq_DOT_Erasure_DOT_ECSubst.
Import MetaRocq.Utils.utils.
Import MetaRocq.Common.BasicAst.
Import MetaRocq.Erasure.EAst.
Import MRMonadNotation.

Fixpoint lookup_env (Σ : global_context) id : option global_decl :=
  match Σ with
  | nil => None
  | hd :: tl =>
    if eq_kername id hd.1 then Some hd.2
    else lookup_env tl id
  end.

Definition declared_constant (Σ : global_context) id decl : Prop :=
  lookup_env Σ id = Some (ConstantDecl decl).

Section Lookups.
  Context (Σ : global_declarations).

  Definition lookup_minductive kn : option mutual_inductive_body :=
    decl <- lookup_env Σ kn;;
    match decl with
    | ConstantDecl _ => None
    | InductiveDecl mdecl => ret mdecl
    end.

  Definition lookup_inductive kn : option (mutual_inductive_body * one_inductive_body) :=
    mdecl <- lookup_minductive (inductive_mind kn) ;;
    idecl <- nth_error mdecl.(ind_bodies) (inductive_ind kn) ;;
    ret (mdecl, idecl).

  Definition lookup_constructor kn c : option (mutual_inductive_body * one_inductive_body * constructor_body) :=
    '(mdecl, idecl) <- lookup_inductive kn ;;
    cdecl <- nth_error idecl.(ind_ctors) c ;;
    ret (mdecl, idecl, cdecl).

End Lookups.

Definition inductive_isprop_and_pars Σ ind :=
  '(mdecl, idecl) <- lookup_inductive Σ ind ;;
  ret (idecl.(ind_propositional), mdecl.(ind_npars)).

Definition constructor_isprop_pars_decl Σ ind c :=
  '(mdecl, idecl, cdecl) <- lookup_constructor Σ ind c ;;
  ret (idecl.(ind_propositional), mdecl.(ind_npars), cdecl).

Definition closed_decl (d : EAst.global_decl) :=
  match d with
  | EAst.ConstantDecl cb =>
    option_default (ELiftSubst.closedn 0) (EAst.cst_body cb) true
  | EAst.InductiveDecl _ => true
  end.

Definition closed_env (Σ : EAst.global_declarations) :=
  forallb (test_snd closed_decl) Σ.

Definition fix_subst (l : mfixpoint term) :=
  let fix aux n :=
      match n with
      | 0 => []
      | S n => tFix l n :: aux n
      end
  in aux (List.length l).

Definition cofix_subst (l : mfixpoint term) :=
  let fix aux n :=
      match n with
      | 0 => []
      | S n => tCoFix l n :: aux n
      end
  in aux (List.length l).

Definition cunfold_fix (mfix : mfixpoint term) (idx : nat) :=
  match List.nth_error mfix idx with
  | Some d =>
    Some (d.(rarg), substl (fix_subst mfix) d.(dbody))
  | None => None
  end.

Definition cunfold_cofix (mfix : mfixpoint term) (idx : nat) :=
  match List.nth_error mfix idx with
  | Some d =>
    Some (d.(rarg), substl (cofix_subst mfix) d.(dbody))
  | None => None
  end.

Definition iota_red npar args (br : list name * term) :=
  substl (List.rev (List.skipn npar args)) br.2.
Module Export MetaRocq.
Module Export Erasure.
Module Export EGlobalEnv.
End EGlobalEnv.

Import Stdlib.Unicode.Utf8.
Import MetaRocq.Utils.utils.
Import MetaRocq.Common.BasicAst.
Import MetaRocq.Erasure.EPrimitive.
Import MetaRocq.Erasure.EAst.
Import MetaRocq.Erasure.EAstUtils.
Import MetaRocq.Erasure.ELiftSubst.
Import MetaRocq.Erasure.ECSubst.
Import MetaRocq.Erasure.EGlobalEnv.
Import Stdlib.ssr.ssreflect.
Import Stdlib.ssr.ssrbool.

Class WcbvFlags := { with_prop_case : bool ; with_guarded_fix : bool ; with_constructor_as_block : bool }.

Definition atom `{wfl : WcbvFlags} Σ t :=
  match t with
  | tBox
  | tCoFix _ _
  | tLambda _ _
  | tLazy _
  | tFix _ _ => true
  | tConstruct ind c [] => negb with_constructor_as_block && isSome (lookup_constructor Σ ind c)
  | _ => false
  end.

Section Wcbv.
  Context {wfl : WcbvFlags}.
  Context (Σ : global_declarations).

  Variant eval_primitive {term term' : Set} (eval : term -> term' -> Set) : prim_val term -> prim_val term' -> Set :=
    | evalPrimInt i : eval_primitive eval (prim_int i) (prim_int i)
    | evalPrimFloat f : eval_primitive eval (prim_float f) (prim_float f)
    | evalPrimString s : eval_primitive eval (prim_string s) (prim_string s)
    | evalPrimArray v def v' def'
      (ev : All2_Set eval v v')
      (ed : eval def def') :
      let a := {| array_default := def; array_value := v |} in
      let a' := {| array_default := def'; array_value := v' |} in
      eval_primitive eval (prim_array a) (prim_array a').

  Variant eval_primitive_ind {term term' : Set} (eval : term -> term' -> Set) (P : forall x y, eval x y -> Type) : forall x y, eval_primitive eval x y -> Type :=
  | evalPrimIntDep i : eval_primitive_ind eval P (prim_int i) (prim_int i) (evalPrimInt eval i)
  | evalPrimFloatDep f : eval_primitive_ind eval P (prim_float f) (prim_float f) (evalPrimFloat eval f)
  | evalPrimStringDep s : eval_primitive_ind eval P (prim_string s) (prim_string s) (evalPrimString eval s)
  | evalPrimArrayDep v def v' def'
    (ev : All2_Set eval v v')
    (ed : eval def def') :
    All2_over ev P -> P _ _ ed ->
    let a := {| array_default := def; array_value := v |} in
    let a' := {| array_default := def'; array_value := v' |} in
    eval_primitive_ind eval P (prim_array a) (prim_array a') (evalPrimArray eval v def v' def' ev ed).

  Local Unset Elimination Schemes.

  Inductive eval : term -> term -> Set :=

  | eval_box a t t' :
      eval a tBox ->
      eval t t' ->
      eval (tApp a t) tBox

  | eval_beta f na b a a' res :
      eval f (tLambda na b) ->
      eval a a' ->
      eval (csubst a' 0 b) res ->
      eval (tApp f a) res

  | eval_zeta na b0 b0' b1 res :
      eval b0 b0' ->
      eval (csubst b0' 0 b1) res ->
      eval (tLetIn na b0 b1) res

  | eval_iota ind pars cdecl discr c args brs br res :
      with_constructor_as_block = false ->
      eval discr (mkApps (tConstruct ind c []) args) ->
      constructor_isprop_pars_decl Σ ind c = Some (false, pars, cdecl) ->
      nth_error brs c = Some br ->
      #|args| = pars + cdecl.(cstr_nargs) ->
      #|skipn pars args| = #|br.1| ->
      eval (iota_red pars args br) res ->
      eval (tCase (ind, pars) discr brs) res

  | eval_iota_block ind pars cdecl discr c args brs br res :
      with_constructor_as_block = true ->
      eval discr (tConstruct ind c args) ->
      constructor_isprop_pars_decl Σ ind c = Some (false, pars, cdecl) ->
      nth_error brs c = Some br ->
      #|args| = pars + cdecl.(cstr_nargs) ->
      #|skipn pars args| = #|br.1| ->
      eval (iota_red pars args br) res ->
      eval (tCase (ind, pars) discr brs) res

  | eval_iota_sing ind pars discr brs n f res :
      with_prop_case ->
      eval discr tBox ->
      inductive_isprop_and_pars Σ ind = Some (true, pars) ->
      brs = [ (n,f) ] ->
      eval (substl (repeat tBox #|n|) f) res ->
      eval (tCase (ind, pars) discr brs) res

  | eval_fix f mfix idx argsv a av fn res :
      forall guarded : with_guarded_fix,
      eval f (mkApps (tFix mfix idx) argsv) ->
      eval a av ->
      cunfold_fix mfix idx = Some (#|argsv|, fn) ->
      eval (tApp (mkApps fn argsv) av) res ->
      eval (tApp f a) res

  | eval_fix_value f mfix idx argsv a av narg fn :
      forall guarded : with_guarded_fix,
      eval f (mkApps (tFix mfix idx) argsv) ->
      eval a av ->
      cunfold_fix mfix idx = Some (narg, fn) ->
      (#|argsv| < narg) ->
      eval (tApp f a) (tApp (mkApps (tFix mfix idx) argsv) av)

  | eval_fix' f mfix idx a av fn res narg :
    forall unguarded : with_guarded_fix = false,
    eval f (tFix mfix idx) ->
    cunfold_fix mfix idx = Some (narg, fn) ->
    eval a av ->
    eval (tApp fn av) res ->
    eval (tApp f a) res

  | eval_cofix_case ip mfix idx args discr narg fn brs res :
      eval discr (mkApps (tCoFix mfix idx) args) ->
      cunfold_cofix mfix idx = Some (narg, fn) ->
      eval (tCase ip (mkApps fn args) brs) res ->
      eval (tCase ip discr brs) res

  | eval_cofix_proj p mfix idx args discr narg fn res :
      eval discr (mkApps (tCoFix mfix idx) args) ->
      cunfold_cofix mfix idx = Some (narg, fn) ->
      eval (tProj p (mkApps fn args)) res ->
      eval (tProj p discr) res

  | eval_delta c decl body (isdecl : declared_constant Σ c decl) res :
      decl.(cst_body) = Some body ->
      eval body res ->
      eval (tConst c) res

  | eval_proj p cdecl discr args a res :
      with_constructor_as_block = false ->
      eval discr (mkApps (tConstruct p.(proj_ind) 0 []) args) ->
      constructor_isprop_pars_decl Σ p.(proj_ind) 0 = Some (false, p.(proj_npars), cdecl) ->
      #|args| = p.(proj_npars) + cdecl.(cstr_nargs) ->
      nth_error args (p.(proj_npars) + p.(proj_arg)) = Some a ->
      eval a res ->
      eval (tProj p discr) res

  | eval_proj_block p cdecl discr args a res :
      with_constructor_as_block = true ->
      eval discr (tConstruct p.(proj_ind) 0 args) ->
      constructor_isprop_pars_decl Σ p.(proj_ind) 0 = Some (false, p.(proj_npars), cdecl) ->
      #|args| = p.(proj_npars) + cdecl.(cstr_nargs) ->
      nth_error args (p.(proj_npars) + p.(proj_arg)) = Some a ->
      eval a res ->
      eval (tProj p discr) res

  | eval_proj_prop p discr :
      with_prop_case ->
      eval discr tBox ->
      inductive_isprop_and_pars Σ p.(proj_ind) = Some (true, p.(proj_npars)) ->
      eval (tProj p discr) tBox

  | eval_construct ind c mdecl idecl cdecl f args a a' :
    with_constructor_as_block = false ->
    lookup_constructor Σ ind c = Some (mdecl, idecl, cdecl) ->
    eval f (mkApps (tConstruct ind c []) args) ->
    #|args| < cstr_arity mdecl cdecl ->
    eval a a' ->
    eval (tApp f a) (tApp (mkApps (tConstruct ind c []) args) a')

  | eval_construct_block ind c mdecl idecl cdecl args args' :
    with_constructor_as_block = true ->
    lookup_constructor Σ ind c = Some (mdecl, idecl, cdecl) ->
    #|args| = cstr_arity mdecl cdecl ->
    All2_Set eval args args' ->
    eval (tConstruct ind c args) (tConstruct ind c args')

  | eval_app_cong f f' a a' :
      eval f f' ->
      ~~ (isLambda f' || (if with_guarded_fix then isFixApp f' else isFix f') || isBox f' || isConstructApp f'
        || isPrimApp f' || isLazyApp f')  ->
      eval a a' ->
      eval (tApp f a) (tApp f' a')

  | eval_prim p p' :
    eval_primitive eval p p' ->
    eval (tPrim p) (tPrim p')

  | eval_force t v v' :
    eval t (tLazy v) ->
    eval v v' ->
    eval (tForce t) v'

  | eval_atom t : atom Σ t -> eval t t.

End Wcbv.
Section eval_rect.

  Variables (wfl : WcbvFlags) (Σ : global_declarations) (P : forall x y, eval Σ x y → Type).

  Lemma eval_rect :
    (∀ (a t t' : term) (e : eval Σ a tBox),
     P a tBox e
     → ∀ e0 : eval Σ t t',
         P t t' e0 → P (tApp a t) tBox (eval_box Σ a t t' e e0))
  → (∀ (f0 : term) (na : name) (b a a' res : term)
       (e : eval Σ f0 (tLambda na b)),
       P f0 (tLambda na b) e
       → ∀ e0 : eval Σ a a',
           P a a' e0
           → ∀ e1 : eval Σ (csubst a' 0 b) res,
               P (csubst a' 0 b) res e1
               → P (tApp f0 a) res (eval_beta Σ f0 na b a a' res e e0 e1))
    → (∀ (na : name) (b0 b0' b1 res : term) (e : eval Σ b0 b0'),
         P b0 b0' e
         → ∀ e0 : eval Σ (csubst b0' 0 b1) res,
             P (csubst b0' 0 b1) res e0
             → P (tLetIn na b0 b1) res (eval_zeta Σ na b0 b0' b1 res e e0))
      → (∀ (ind : inductive) (pars : nat) (cdecl : constructor_body)
           (discr : term) (c : nat) (args : list term)
           (brs : list (list name × term)) (br : list name × term)
           (res : term) (e : with_constructor_as_block = false)
           (e0 : eval Σ discr (mkApps (tConstruct ind c []) args)),
           P discr (mkApps (tConstruct ind c []) args) e0
           → ∀ (e1 : constructor_isprop_pars_decl Σ ind c =
                     Some (false, pars, cdecl)) (e2 :
                                                 nth_error brs c =
                                                 Some br)
               (e3 : #|args| = pars + cstr_nargs cdecl)
               (e4 : #|skipn pars args| = #|br.1|)
               (e5 : eval Σ (iota_red pars args br) res),
               P (iota_red pars args br) res e5
               → P (tCase (ind, pars) discr brs) res
                   (eval_iota Σ ind pars cdecl discr c args brs br res e e0
                      e1 e2 e3 e4 e5))
        → (∀ (ind : inductive) (pars : nat) (cdecl : constructor_body)
             (discr : term) (c : nat) (args : list term)
             (brs : list (list name × term)) (br : list name × term)
             (res : term) (e : with_constructor_as_block = true)
             (e0 : eval Σ discr (tConstruct ind c args)),
             P discr (tConstruct ind c args) e0
             → ∀ (e1 : constructor_isprop_pars_decl Σ ind c =
                       Some (false, pars, cdecl))
                 (e2 : nth_error brs c = Some br)
                 (e3 : #|args| = pars + cstr_nargs cdecl)
                 (e4 : #|skipn pars args| = #|br.1|)
                 (e5 : eval Σ (iota_red pars args br) res),
                 P (iota_red pars args br) res e5
                 → P (tCase (ind, pars) discr brs) res
                     (eval_iota_block Σ ind pars cdecl discr c args brs br
                        res e e0 e1 e2 e3 e4 e5))
          → (∀ (ind : inductive) (pars : nat) (discr : term)
               (brs : list (list name × term)) (n : list name)
               (f4 res : term) (i : with_prop_case)
               (e : eval Σ discr tBox),
               P discr tBox e
               → ∀ (e0 : inductive_isprop_and_pars Σ ind = Some (true, pars))
                   (e1 : brs = [(n, f4)]) (e2 : eval Σ
                                                 (substl
                                                 (repeat tBox #|n|) f4) res),
                   P (substl (repeat tBox #|n|) f4) res e2
                   → P (tCase (ind, pars) discr brs) res
                       (eval_iota_sing Σ ind pars discr brs n f4 res i e e0
                          e1 e2))
            → (∀ (f5 : term) (mfix : mfixpoint term)
                 (idx : nat) (argsv : list term) (a av fn res : term)
                 (guarded : with_guarded_fix) (e :
                                               eval Σ f5
                                                 (mkApps
                                                 (tFix mfix idx) argsv)),
                 P f5 (mkApps (tFix mfix idx) argsv) e
                 → ∀ e0 : eval Σ a av,
                     P a av e0
                     → ∀ (e1 : cunfold_fix mfix idx = Some (#|argsv|, fn))
                         (e2 : eval Σ (tApp (mkApps fn argsv) av) res),
                         P (tApp (mkApps fn argsv) av) res e2
                         → P (tApp f5 a) res
                             (eval_fix Σ f5 mfix idx argsv a av fn res
                                guarded e e0 e1 e2))
              → (∀ (f6 : term) (mfix : mfixpoint term)
                   (idx : nat) (argsv : list term)
                   (a av : term) (narg : nat) (fn : term)
                   (guarded : with_guarded_fix) (e :
                                                 eval Σ f6
                                                 (mkApps
                                                 (tFix mfix idx) argsv)),
                   P f6 (mkApps (tFix mfix idx) argsv) e
                   → ∀ e0 : eval Σ a av,
                       P a av e0
                       → ∀ (e1 : cunfold_fix mfix idx = Some (narg, fn))
                           (l : #|argsv| < narg),
                           P (tApp f6 a)
                             (tApp (mkApps (tFix mfix idx) argsv) av)
                             (eval_fix_value Σ f6 mfix idx argsv a av narg fn
                                guarded e e0 e1 l))
                → (∀ (f7 : term) (mfix : mfixpoint term)
                     (idx : nat) (a av fn res : term)
                     (narg : nat) (unguarded : with_guarded_fix = false)
                     (e : eval Σ f7 (tFix mfix idx)),
                     P f7 (tFix mfix idx) e
                     → ∀ (e0 : cunfold_fix mfix idx = Some (narg, fn))
                         (e1 : eval Σ a av),
                         P a av e1
                         → ∀ e2 : eval Σ (tApp fn av) res,
                             P (tApp fn av) res e2
                             → P (tApp f7 a) res
                                 (eval_fix' Σ f7 mfix idx a av fn res narg
                                    unguarded e e0 e1 e2))
                  → (∀ (ip : inductive × nat) (mfix : mfixpoint term)
                       (idx : nat) (args : list term)
                       (discr : term) (narg : nat)
                       (fn : term) (brs : list (list name × term))
                       (res : term) (e : eval Σ discr
                                           (mkApps (tCoFix mfix idx) args)),
                       P discr (mkApps (tCoFix mfix idx) args) e
                       → ∀ (e0 : cunfold_cofix mfix idx = Some (narg, fn))
                           (e1 : eval Σ (tCase ip (mkApps fn args) brs) res),
                           P (tCase ip (mkApps fn args) brs) res e1
                           → P (tCase ip discr brs) res
                               (eval_cofix_case Σ ip mfix idx args discr narg
                                  fn brs res e e0 e1))
                    → (∀ (p : projection) (mfix : mfixpoint term)
                         (idx : nat) (args : list term)
                         (discr : term) (narg : nat)
                         (fn res : term) (e : eval Σ discr
                                                (mkApps
                                                 (tCoFix mfix idx) args)),
                         P discr (mkApps (tCoFix mfix idx) args) e
                         → ∀ (e0 : cunfold_cofix mfix idx = Some (narg, fn))
                             (e1 : eval Σ (tProj p (mkApps fn args)) res),
                             P (tProj p (mkApps fn args)) res e1
                             → P (tProj p discr) res
                                 (eval_cofix_proj Σ p mfix idx args discr
                                    narg fn res e e0 e1))
                      → (∀ (c : kername) (decl : constant_body)
                           (body : term) (isdecl :
                                          declared_constant Σ c decl)
                           (res : term) (e : cst_body decl = Some body)
                           (e0 : eval Σ body res),
                           P body res e0
                           → P (tConst c) res
                               (eval_delta Σ c decl body isdecl res e e0))
                        → (∀ (p : projection) (cdecl : constructor_body)
                             (discr : term) (args : list term)
                             (a res : term) (e : with_constructor_as_block =
                                                 false)
                             (e0 : eval Σ discr
                                     (mkApps (tConstruct (proj_ind p) 0 [])
                                        args)),
                             P discr
                               (mkApps (tConstruct (proj_ind p) 0 []) args)
                               e0
                             → ∀ (e1 : constructor_isprop_pars_decl Σ
                                         (proj_ind p) 0 =
                                       Some (false, proj_npars p, cdecl))
                                 (e2 : #|args| =
                                       proj_npars p + cstr_nargs cdecl)
                                 (e3 : nth_error args
                                         (proj_npars p + proj_arg p) =
                                       Some a) (e4 : eval Σ a res),
                                 P a res e4
                                 → P (tProj p discr) res
                                     (eval_proj Σ p cdecl discr args a res e
                                        e0 e1 e2 e3 e4))
                          → (∀ (p : projection) (cdecl : constructor_body)
                               (discr : term) (args : list term)
                               (a res : term) (e :
                                               with_constructor_as_block =
                                               true)
                               (e0 : eval Σ discr
                                       (tConstruct (proj_ind p) 0 args)),
                               P discr (tConstruct (proj_ind p) 0 args) e0
                               → ∀ (e1 : constructor_isprop_pars_decl Σ
                                           (proj_ind p) 0 =
                                         Some (false, proj_npars p, cdecl))
                                   (e2 : #|args| =
                                         proj_npars p + cstr_nargs cdecl)
                                   (e3 : nth_error args
                                           (proj_npars p + proj_arg p) =
                                         Some a) (e4 : eval Σ a res),
                                   P a res e4
                                   → P (tProj p discr) res
                                       (eval_proj_block Σ p cdecl discr args
                                          a res e e0 e1 e2 e3 e4))
                            → (∀ (p : projection)
                                 (discr : term) (i : with_prop_case)
                                 (e : eval Σ discr tBox),
                                 P discr tBox e
                                 → ∀ e0 : inductive_isprop_and_pars Σ
                                            (proj_ind p) =
                                          Some (true, proj_npars p),
                                     P (tProj p discr) tBox
                                       (eval_proj_prop Σ p discr i e e0))
                              → (∀ (ind : inductive)
                                   (c : nat) (mdecl : mutual_inductive_body)
                                   (idecl : one_inductive_body)
                                   (cdecl : constructor_body)
                                   (f14 : term) (args : list term)
                                   (a a' : term) (e :
                                                 with_constructor_as_block =
                                                 false)
                                   (e0 : lookup_constructor Σ ind c =
                                         Some (mdecl, idecl, cdecl))
                                   (e1 : eval Σ f14
                                           (mkApps (tConstruct ind c []) args)),
                                   P f14 (mkApps (tConstruct ind c []) args)
                                     e1
                                   → ∀ (l : #|args| < cstr_arity mdecl cdecl)
                                       (e2 : eval Σ a a'),
                                       P a a' e2
                                       → P (tApp f14 a)
                                           (tApp
                                              (mkApps
                                                 (tConstruct ind c []) args)
                                              a')
                                           (eval_construct Σ ind c mdecl
                                              idecl cdecl f14 args a a' e e0
                                              e1 l e2))
                                → (∀ (ind : inductive)
                                     (c : nat) (mdecl : mutual_inductive_body)
                                     (idecl : one_inductive_body)
                                     (cdecl : constructor_body)
                                     (args args' :
                                      list term) (e :
                                                 with_constructor_as_block =
                                                 true)
                                     (e0 : lookup_constructor Σ ind c =
                                           Some (mdecl, idecl, cdecl))
                                     (e1 : #|args| = cstr_arity mdecl cdecl)
                                     (a : All2_Set (eval Σ) args args')
                                     (iha : All2_over a P),
                                     P (tConstruct ind c args)
                                       (tConstruct ind c args')
                                       (eval_construct_block Σ ind c mdecl
                                          idecl cdecl args args' e e0 e1 a))
                                  → (∀ (f16 f' a a' : term)
                                       (e : eval Σ f16 f'),
                                       P f16 f' e
                                       → ∀ (i : ~~
                                                (isLambda f'
                                                 ||
                                                 (if with_guarded_fix
                                                 then isFixApp f'
                                                 else isFix f') ||
                                                 isBox f'
                                                 ||
                                                 isConstructApp f'
                                                 || isPrimApp f' || isLazyApp f'))
                                           (e0 : eval Σ a a'),
                                           P a a' e0
                                           → P (tApp f16 a)
                                               (tApp f' a')
                                               (eval_app_cong Σ f16 f' a a' e
                                                 i e0)) ->

    (forall p p' (ev : eval_primitive (eval Σ) p p'),
      eval_primitive_ind _ P _ _ ev ->
      P (tPrim p) (tPrim p') (eval_prim _ _ _ ev)) ->
    (forall t t' v (ev1 : eval Σ t (tLazy t')) (ev2 : eval Σ t' v),
      P _ _ ev1 -> P _ _ ev2 ->
      P (tForce t) v (eval_force _ t t' v ev1 ev2))

    → (∀ (t : term) (i : atom Σ t),
          P t t (eval_atom Σ t i))
      → ∀ (t t0 : term) (e : eval Σ t t0),
          P t t0 e.
Admitted.
  Definition eval_ind := eval_rect.

End eval_rect.

#[register=no] Scheme eval_nondep := Minimality for eval Sort Prop.

Lemma closedn_mkApps k f args : closedn k (mkApps f args) = closedn k f && forallb (closedn k) args.
Admitted.

Lemma eval_closed {wfl : WcbvFlags} Σ :
  closed_env Σ ->
  forall t u, closed t -> eval Σ t u -> closed u.
Proof.
  move=> clΣ t u Hc ev.
move: Hc.
  induction ev; simpl in *; auto;
    (move/andP=> [/andP[Hc Hc'] Hc''] || move/andP=> [Hc Hc'] || move=>Hc); auto.
  -
 eapply IHev3.
rewrite ECSubst.closed_subst //.
auto.
    eapply closedn_subst; tea.
cbn.
rewrite andb_true_r.
auto.
cbn.
auto.
  -
 eapply IHev2.
    rewrite ECSubst.closed_subst; auto.
    eapply closedn_subst; tea.
cbn.
rewrite andb_true_r.
auto.
  -
 specialize (IHev1 Hc).
    move: IHev1; rewrite closedn_mkApps => /andP[] _ clargs.
    apply IHev2.
rewrite /iota_red.
    eapply closed_substl.
now rewrite forallb_rev forallb_skipn.
    len.
rewrite e4.
🛠️ Intermediate Coq File (useful for debugging if minimization did not go as far as you wanted)
🛠️ 📜 Intermediate Coq File log (useful for debugging if minimization did not go as far as you wanted)
📜 Build Log (contains the Coq error message) (truncated to last 8.0KiB; full 8.2MiB file on GitHub Actions Artifacts under build.log)
-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1634, characters 17-19:
Error: The variable e4 was not found in the current environment.

Command exited with non-zero status 1
theories/EWcbvEval.vo (real: 14.01, user: 13.47, sys: 0.24, mem: 988420 ko)
make[3]: *** [Makefile.erasure:813: theories/EWcbvEval.vo] Error 1
make[3]: *** [theories/EWcbvEval.vo] Deleting file 'theories/EWcbvEval.glob'
make[2]: *** [Makefile.erasure:411: all] Error 2
make[2]: Leaving directory '/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/erasure'
make[1]: *** [Makefile:11: theory] Error 2
make[1]: Leaving directory '/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/erasure'
make: *** [Makefile:164: erasure] Error 2
+ code=2
+ printf '\n%s exit code: %s\n' metarocq 2
+ '[' metarocq '!=' stdlib_test ']'
+ echo 'Aggregating timing log...'
Aggregating timing log...
+ echo

+ tools/make-one-time-file.py --real metarocq.log
    Time |  Peak Mem | File Name                    
----------------------------------------------------
0m23.88s | 988420 ko | Total Time / Peak Mem        
----------------------------------------------------
0m14.01s | 988420 ko | EWcbvEval.vo                 
0m04.56s | 854340 ko | EArities.vo                  
0m02.99s | 924688 ko | Extraction.vo                
0m02.04s | 891952 ko | SafeTemplateChecker.vo       
0m00.14s |  18576 ko | .Makefile.plugin.d           
0m00.14s |  18008 ko | .Makefile.safecheckerplugin.d
+ '[' '' ']'
+ exit 2
/github/workspace/builds/coq /github/workspace
::endgroup::
📜 🔎 Minimization Log (truncated to last 8.0KiB; full 4.7MiB file on GitHub Actions Artifacts under bug.log)
tolerance will be eventually removed. Insert parentheses or try to lower
the level at which the top symbol of this expression is parsed.
[level-tolerance,deprecated-since-9.2,deprecated,parsing,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1148, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1149, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1150, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1151, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1152, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1153, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1154, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1155, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1180, characters 55-62:
Warning: In term, tolerating this expression at a higher level than expected.
This tolerance will be eventually removed. Insert parentheses or try to lower
the level at which the top symbol of this expression is parsed.
[level-tolerance,deprecated-since-9.2,deprecated,parsing,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1180, characters 55-62:
Warning: In term, tolerating this expression at a higher level than expected.
This tolerance will be eventually removed. Insert parentheses or try to lower
the level at which the top symbol of this expression is parsed.
[level-tolerance,deprecated-since-9.2,deprecated,parsing,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1181, characters 75-82:
Warning: In term, tolerating this expression at a higher level than expected.
This tolerance will be eventually removed. Insert parentheses or try to lower
the level at which the top symbol of this expression is parsed.
[level-tolerance,deprecated-since-9.2,deprecated,parsing,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1181, characters 75-82:
Warning: In term, tolerating this expression at a higher level than expected.
This tolerance will be eventually removed. Insert parentheses or try to lower
the level at which the top symbol of this expression is parsed.
[level-tolerance,deprecated-since-9.2,deprecated,parsing,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1188, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1254, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1255, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1257, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1258, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1259, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1260, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1349, characters 4-12:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1350, characters 4-82:
Warning: Postfix notations (i.e. starting with a nonterminal symbol and
ending with a terminal symbol) should usually be at level 1 (default).
[postfix-notation-not-level-1,parsing,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1369, characters 16-43:
Warning: In term, tolerating this expression at a higher level than expected.
This tolerance will be eventually removed. Insert parentheses or try to lower
the level at which the top symbol of this expression is parsed.
[level-tolerance,deprecated-since-9.2,deprecated,parsing,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1389, characters 20-44:
Warning: In term, tolerating this expression at a higher level than expected.
This tolerance will be eventually removed. Insert parentheses or try to lower
the level at which the top symbol of this expression is parsed.
[level-tolerance,deprecated-since-9.2,deprecated,parsing,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1941, characters 2-10:
Warning: Use of "Notation" keyword for abbreviations is deprecated, use
"Abbreviation" instead.
[notation-for-abbreviation,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 1960, characters 2-50:
Warning: Implicitly declaring hint databases is deprecated. Please explicitly
create "pcuic"
[implicit-create-hint-db,deprecated-since-9.2,deprecated,default]
File "/tmp/tmpd0igohzk/MetaRocq/Erasure/EWcbvEval.v", line 2114, characters 38-63:
Error:
In environment
term : Type
i : PrimInt63.int
The term "(primInt; primIntModel i)" has type "∑ y, ?P y"
while it is expected to have type "prim_val".


�[93mIntermediate code not saved.�[0m
Failed to do everything at once; trying one at a time.
Admitting definitions unsuccessful.
No successful changes.

I will now attempt to add Proof using lines
�[92m
Adding Proof using lines successful.�[0m
Failed to do everything at once; trying one at a time.
Adding Proof using lines unsuccessful.
No successful changes.

I will now attempt to export modules
Module exportation successful

I will now attempt to split imports and exports
Import/Export splitting successful

I will now attempt to split := definitions
One-line definition splitting successful

I will now attempt to lift Requires to the top of the file while inserting option settings

I will now attempt to lift Requires to the top of the file while inserting option settings

I will now attempt to remove all lines, one at a time

If you have any comments on your experience of the minimizer, please share them in a reply (possibly tagging @JasonGross).
If you believe there's a bug in the bug minimizer, please report it on the bug minimizer issue tracker.

@coqbot-app
Copy link
Contributor

coqbot-app bot commented Nov 19, 2025

Minimization interrupted by timeout, being automatically continued. Partially Minimized File /home/runner/work/run-coq-bug-minimizer/run-coq-bug-minimizer/builds/coq/coq-failing/_build_ci/metarocq/erasure/theories/EWcbvEval.v in 5h 15m 7s (from ci-metarocq) (interrupted by timeout, being automatically continued) (full log on GitHub Actions - verbose log)
⭐ ⏱️ Partially Minimized Coq File (timeout) (truncated to first and last 32KiB; full 61KiB file on GitHub Actions Artifacts under bug.v)
(* -*- mode: coq; coq-prog-args: ("-emacs" "-q" "-w" "-deprecated-native-compiler-option" "-native-compiler" "no" "-coqlib" "/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq//" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/utils/theories" "MetaRocq.Utils" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/common/theories" "MetaRocq.Common" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/pcuic/theories" "MetaRocq.PCUIC" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/safechecker-plugin/theories" "MetaRocq.SafeCheckerPlugin" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/template-pcuic/theories" "MetaRocq.TemplatePCUIC" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/template-rocq/theories" "MetaRocq.Template" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/safechecker/theories" "MetaRocq.SafeChecker" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/erasure/theories" "MetaRocq.Erasure" "-Q" "/github/workspace/cwd" "Top" "-Q" "/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Equations" "Equations" "-Q" "/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Ltac2" "Ltac2" "-Q" "/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Stdlib" "Stdlib" "-I" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/template-rocq" "-top" "Top.bug_01") -*- *)
(* File reduced by coq-bug-minimizer from original input, then from 2155 lines to 516 lines, then from 530 lines to 1482 lines, then from 1487 lines to 517 lines, then from 531 lines to 1202 lines, then from 1208 lines to 611 lines, then from 625 lines to 1214 lines, then from 1217 lines to 672 lines, then from 686 lines to 1728 lines, then from 1733 lines to 780 lines, then from 794 lines to 1587 lines, then from 1593 lines to 789 lines, then from 803 lines to 1613 lines, then from 1619 lines to 845 lines, then from 859 lines to 1466 lines, then from 1469 lines to 945 lines, then from 959 lines to 1859 lines, then from 1865 lines to 1022 lines, then from 1036 lines to 3851 lines, then from 3850 lines to 2939 lines, then from 2891 lines to 1000 lines, then from 1012 lines to 2696 lines, then from 2701 lines to 1031 lines, then from 1042 lines to 1329 lines, then from 1336 lines to 1046 lines, then from 1057 lines to 4161 lines, then from 4127 lines to 1087 lines, then from 1098 lines to 2272 lines, then from 2275 lines to 1127 lines, then from 1139 lines to 1975 lines, then from 1982 lines to 1195 lines, then from 1207 lines to 1563 lines, then from 1570 lines to 1211 lines, then from 1223 lines to 1734 lines, then from 1740 lines to 1737 lines *)
(* coqc version 9.2+alpha compiled with OCaml 4.14.2
   coqtop version 9.2+alpha
   Expected coqc runtime on this file: 1.118 sec
   Expected coqc peak memory usage on this file: 841584.0 kb *)




Require Coq.Init.Ltac.
Module Export AdmitTactic.
Module Import LocalFalse.
Inductive False : Prop := .
End LocalFalse.
Axiom proof_admitted : False.
Import Coq.Init.Ltac.
Tactic Notation "admit" := abstract case proof_admitted.
End AdmitTactic.

Require MetaRocq.Utils.MRUtils.
Require Corelib.BinNums.IntDef.
Require Corelib.BinNums.NatDef.
Require Corelib.BinNums.PosDef.
Require Corelib.Classes.CRelationClasses.
Require Corelib.Classes.Morphisms.
Require Corelib.Classes.Morphisms_Prop.
Require Corelib.Classes.RelationClasses.
Require Corelib.Init.Byte.
Require Corelib.Init.Sumbool.
Require Corelib.Lists.ListDef.
Require Corelib.Numbers.BinNums.
Require Corelib.Program.Basics.
Require Corelib.Program.Tactics.
Require Corelib.Program.Wf.
Require Corelib.Relations.Relation_Definitions.
Require Corelib.Setoids.Setoid.
Require Corelib.extraction.Extraction.
Require Corelib.ssr.ssrbool.
Require Corelib.ssr.ssreflect.
Require MetaRocq.Utils.MRSquash.
Require Stdlib.Classes.DecidableClass.
Require Stdlib.Logic.Decidable.
Require Stdlib.Logic.EqdepFacts.
Require Stdlib.Logic.FunctionalExtensionality.
Require Stdlib.Logic.HLevelsBase.
Require Stdlib.Sets.Relations_1.
Require Stdlib.Unicode.Utf8_core.
Require Stdlib.Wellfounded.Inverse_Image.
Require Stdlib.micromega.ZifyClasses.
Require Stdlib.setoid_ring.Algebra_syntax.
Require Stdlib.BinNums.IntDef.
Require Stdlib.BinNums.NatDef.
Require Stdlib.BinNums.PosDef.
Require Stdlib.Classes.CRelationClasses.
Require Stdlib.Classes.Morphisms.
Require Stdlib.Classes.Morphisms_Prop.
Require Stdlib.Classes.RelationClasses.
Require Stdlib.Init.Byte.
Require Stdlib.Init.Sumbool.
Require Stdlib.Lists.ListDef.
Require Stdlib.Logic.Eqdep_dec.
Require Stdlib.Numbers.BinNums.
Require Stdlib.Program.Basics.
Require Stdlib.Program.Tactics.
Require Stdlib.Program.Wf.
Require Stdlib.Relations.Relation_Definitions.
Require Stdlib.Setoids.Setoid.
Require Stdlib.Unicode.Utf8.
Require Stdlib.Wellfounded.Well_Ordering.
Require Stdlib.extraction.Extraction.
Require Stdlib.ssr.ssrbool.
Require Stdlib.ssr.ssreflect.
Require Equations.Init.
Require Stdlib.Bool.Bool.
Require Stdlib.Relations.Relation_Operators.
Require Stdlib.Wellfounded.Inclusion.
Require Equations.Prop.SigmaNotations.
Require Equations.Signature.
Require Stdlib.Relations.Operators_Properties.
Require Stdlib.Wellfounded.Disjoint_Union.
Require Stdlib.Wellfounded.Transitive_Closure.
Require Equations.CoreTactics.
Require Stdlib.PArith.BinPosDef.
Require Stdlib.Relations.Relations.
Require Stdlib.Wellfounded.Union.
Require Equations.Type.Logic.
Require Stdlib.Numbers.NumPrelude.
Require Equations.Prop.Logic.
Require Equations.Type.Relation.
Require Stdlib.Wellfounded.Lexicographic_Product.
Require Equations.Type.Relation_Properties.
Require MetaRocq.Utils.MRProd.
Require Stdlib.Structures.Equalities.
Require Equations.Prop.Classes.
Require Equations.Prop.EqDec.
Require MetaRocq.Utils.MRRelations.
Require Equations.Prop.DepElim.
Require Equations.Prop.FunctionalInduction.
Require Stdlib.Structures.Orders.
Require Equations.Prop.Constants.
Require Stdlib.Structures.OrdersTac.
Require Stdlib.Structures.OrdersFacts.
Require Stdlib.Structures.GenericMinMax.
Require Stdlib.Numbers.NatInt.NZAxioms.
Require Stdlib.Numbers.NatInt.NZBase.
Require Stdlib.Numbers.NatInt.NZAdd.
Require Stdlib.Numbers.NatInt.NZMul.
Require Stdlib.Numbers.NatInt.NZOrder.
Require Stdlib.Numbers.NatInt.NZAddOrder.
Require Stdlib.Numbers.NatInt.NZMulOrder.
Require Stdlib.Numbers.NatInt.NZDiv.
Require Stdlib.Numbers.NatInt.NZGcd.
Require Stdlib.Numbers.NatInt.NZParity.
Require Stdlib.Numbers.NatInt.NZPow.
Require Stdlib.Numbers.NatInt.NZSqrt.
Require Stdlib.Numbers.NatInt.NZLog.
Require Stdlib.Numbers.NatInt.NZBits.
Require Stdlib.Numbers.Integer.Abstract.ZAxioms.
Require Stdlib.Numbers.Natural.Abstract.NAxioms.
Require Stdlib.Numbers.Integer.Abstract.ZBase.
Require Stdlib.Numbers.Natural.Abstract.NBase.
Require Stdlib.Numbers.Integer.Abstract.ZAdd.
Require Stdlib.Numbers.Natural.Abstract.NAdd.
Require Stdlib.Numbers.Integer.Abstract.ZMul.
Require Stdlib.Numbers.Natural.Abstract.NOrder.
Require Stdlib.Numbers.Integer.Abstract.ZLt.
Require Stdlib.Numbers.Natural.Abstract.NAddOrder.
Require Stdlib.Numbers.Integer.Abstract.ZAddOrder.
Require Stdlib.Numbers.Natural.Abstract.NMulOrder.
Require Stdlib.Numbers.Integer.Abstract.ZMulOrder.
Require Stdlib.Numbers.Natural.Abstract.NSub.
Require Stdlib.Numbers.Integer.Abstract.ZMaxMin.
Require Stdlib.Numbers.Integer.Abstract.ZParity.
Require Stdlib.Numbers.Integer.Abstract.ZSgnAbs.
Require Stdlib.Numbers.Natural.Abstract.NDiv.
Require Stdlib.Numbers.Natural.Abstract.NGcd.
Require Stdlib.Numbers.Natural.Abstract.NMaxMin.
Require Stdlib.Numbers.Natural.Abstract.NParity.
Require Stdlib.Numbers.Natural.Abstract.NSqrt.
Require Stdlib.Numbers.Integer.Abstract.ZDivFloor.
Require Stdlib.Numbers.Integer.Abstract.ZDivTrunc.
Require Stdlib.Numbers.Integer.Abstract.ZGcd.
Require Stdlib.Numbers.Natural.Abstract.NDiv0.
Require Stdlib.Numbers.Natural.Abstract.NPow.
Require Stdlib.Numbers.Integer.Abstract.ZPow.
Require Stdlib.Numbers.Natural.Abstract.NLcm.
Require Stdlib.Numbers.Natural.Abstract.NLog.
Require Stdlib.Numbers.Integer.Abstract.ZBits.
Require Stdlib.Numbers.Integer.Abstract.ZLcm.
Require Stdlib.Numbers.Natural.Abstract.NBits.
Require Stdlib.Numbers.Natural.Abstract.NLcm0.
Require Stdlib.Numbers.Integer.Abstract.ZProperties.
Require Stdlib.Numbers.Natural.Abstract.NProperties.
Require Stdlib.Arith.PeanoNat.
Require Stdlib.Arith.Between.
Require Stdlib.Arith.Compare_dec.
Require Stdlib.Arith.EqNat.
Require Stdlib.Arith.Factorial.
Require Stdlib.Arith.Wf_nat.
Require Stdlib.Arith.Peano_dec.
Require Stdlib.Lists.List.
Require Stdlib.Wellfounded.List_Extension.
Require Stdlib.micromega.Refl.
Require Stdlib.Sorting.Sorted.
Require Stdlib.micromega.Tauto.
Require Stdlib.Lists.ListTactics.
Require Stdlib.Sorting.SetoidList.
Require Stdlib.Wellfounded.Lexicographic_Exponentiation.
Require Stdlib.PArith.BinPos.
Require Stdlib.Arith.Arith_base.
Require Stdlib.PArith.POrderedType.
Require Stdlib.PArith.Pnat.
Require Stdlib.Vectors.Fin.
Require Stdlib.NArith.BinNatDef.
Require Stdlib.PArith.PArith.
Require Stdlib.Vectors.VectorDef.
Require Stdlib.NArith.BinNat.
Require Stdlib.setoid_ring.BinList.
Require Stdlib.setoid_ring.Ring_theory.
Require Stdlib.NArith.Nnat.
Require Stdlib.Wellfounded.Wellfounded.
Require Stdlib.Vectors.VectorSpec.
Require Stdlib.ZArith.BinIntDef.
Require Stdlib.Vectors.VectorEq.
Require Stdlib.Vectors.Vector.
Require Stdlib.Strings.Byte.
Require Stdlib.Strings.Ascii.
Require Stdlib.micromega.DeclConstantZ.
Require Stdlib.Vectors.Bvector.
Require Equations.Prop.Subterm.
Require Stdlib.ZArith.BinInt.
Require Stdlib.ZArith.Zcompare.
Require Stdlib.ZArith.Zeven.
Require Equations.Prop.Tactics.
Require Stdlib.ZArith.Zpow_def.
Require Stdlib.setoid_ring.Ncring.
Require Stdlib.micromega.Env.
Require Stdlib.micromega.VarMap.
Require Stdlib.micromega.EnvRing.
Require Stdlib.setoid_ring.Ring_polynom.
Require Stdlib.setoid_ring.InitialRing.
Require Stdlib.ZArith.Znat.
Require Stdlib.ZArith.Zorder.
Require Stdlib.setoid_ring.Ncring_polynom.
Require Stdlib.setoid_ring.Ring_tac.
Require Stdlib.ZArith.Zmax.
Require Stdlib.ZArith.Zmin.
Require Stdlib.ZArith.Zminmax.
Require Stdlib.ZArith.Zmisc.
Require Stdlib.ZArith.auxiliary.
Require Stdlib.omega.OmegaLemmas.
Require Stdlib.setoid_ring.Ncring_initial.
Require Stdlib.setoid_ring.Ring_base.
Require Stdlib.setoid_ring.Ncring_tac.
Require Stdlib.setoid_ring.Ring.
Require Stdlib.ZArith.ZArith_dec.
Require Stdlib.micromega.OrderedRing.
Require Stdlib.ZArith.Wf_Z.
Require Stdlib.setoid_ring.ArithRing.
Require Stdlib.setoid_ring.Cring.
Require Stdlib.setoid_ring.ZArithRing.
Require Stdlib.ZArith.Zbool.
Require Stdlib.setoid_ring.Integral_domain.
Require Stdlib.ZArith.Zabs.
Require Equations.Prop.NoConfusion.
Require Stdlib.micromega.RingMicromega.
Require Stdlib.nsatz.NsatzTactic.
Require Equations.Prop.EqDecInstances.
Require Equations.Prop.Loader.
Require Equations.Prop.Telescopes.
Require Stdlib.ZArith.Zhints.
Require Stdlib.micromega.ZCoeff.
Require Equations.Prop.Equations.
Require Stdlib.Arith.Arith.
Require Stdlib.ZArith.ZArith_base.
Require Stdlib.micromega.ZifyInst.
Require MetaRocq.Utils.ReflectEq.
Require Stdlib.Strings.String.
Require Stdlib.micromega.Zify.
Require Stdlib.omega.PreOmega.
Require Stdlib.ZArith.Zcomplements.
Require Stdlib.ZArith.Zpower.
Require Stdlib.ZArith.Zdiv.
Require Stdlib.micromega.ZMicromega.
Require Stdlib.micromega.Lia.
Require Stdlib.ZArith.Zdiv_facts.
Require Stdlib.ZArith.Zdivisibility.
Require Stdlib.ZArith.ZModOffset.
Require Stdlib.ZArith.Zcong.
Require Stdlib.btauto.Algebra.
Require Stdlib.btauto.Reflect.
Require Stdlib.micromega.ZArith_hints.
Require Stdlib.btauto.Btauto.
Require Stdlib.ZArith.Zbitwise.
Require Stdlib.ZArith.ZNsatz.
Require Stdlib.ZArith.Znumtheory.
Require Stdlib.ZArith.ZArith.
Require MetaRocq.Utils.MRPrelude.
Require MetaRocq.Utils.MRReflect.
Require MetaRocq.Utils.MRList.
Require MetaRocq.Utils.MROption.
Require MetaRocq.Utils.All_Forall.

Module MetaRocq_DOT_Utils_DOT_monad_utils_WRAPPED.
Module monad_utils.
Import Stdlib.Arith.Arith Stdlib.Lists.List.
Import MetaRocq.Utils.All_Forall MetaRocq.Utils.MRSquash.
Import Equations.Prop.Equations.
Coercion is_true : bool >-> Sortclass.

Import ListNotations.

Set Universe Polymorphism.
Set Polymorphic Inductive Cumulativity.

Class Monad@{d c} (m : Type@{d} -> Type@{c}) : Type :=
{ ret : forall {t : Type@{d}}, t -> m t
; bind : forall {t u : Type@{d}}, m t -> (t -> m u) -> m u
}.

Class MonadExc E (m : Type -> Type) : Type :=
{ raise : forall {T}, E -> m T
; catch : forall {T}, m T -> (E -> m T) -> m T
}.

Module MRMonadNotation.
  Declare Scope monad_scope.
  Delimit Scope monad_scope with monad.

  Notation "c >>= f" := (@bind _ _ _ _ c f) (at level 50, left associativity) : monad_scope.
  Notation "f =<< c" := (@bind _ _ _ _ c f) (at level 51, right associativity) : monad_scope.

  Notation "'mlet' x <- c1 ;; c2" := (@bind _ _ _ _ c1 (fun x => c2))
    (at level 100, c1 at next level, right associativity, x pattern) : monad_scope.

  Notation "'mlet' ' pat <- c1 ;; c2" := (@bind _ _ _ _ c1 (fun x => match x with pat => c2 end))
    (at level 100, pat pattern, c1 at next level, right associativity) : monad_scope.

  Notation "x <- c1 ;; c2" := (@bind _ _ _ _ c1 (fun x => c2))
    (at level 100, c1 at next level, right associativity) : monad_scope.

  Notation "' pat <- c1 ;; c2" := (@bind _ _ _ _ c1 (fun x => match x with pat => c2 end))
    (at level 100, pat pattern, c1 at next level, right associativity) : monad_scope.

  Notation "e1 ;; e2" := (_ <- e1%monad ;; e2%monad)%monad
    (at level 100, right associativity) : monad_scope.
End MRMonadNotation.

Import MRMonadNotation.

#[global] Instance option_monad : Monad option :=
  {| ret A a := Some a ;
     bind A B m f :=
       match m with
       | Some a => f a
       | None => None
       end
  |}.

#[global] Instance id_monad : Monad (fun x => x) :=
  {| ret A a := a ;
     bind A B m f := f m
  |}.

#[global] Instance option_monad_exc : MonadExc unit option :=
{| raise T _ := None ;
    catch T m f :=
      match m with
      | Some a => Some a
      | None => f tt
      end
|}.

Open Scope monad.

Section MapOpt.
  Context {A} {B} (f : A -> option B).

  Fixpoint mapopt (l : list A) : option (list B) :=
    match l with
    | nil => ret nil
    | x :: xs => x' <- f x ;;
                xs' <- mapopt xs ;;
                ret (x' :: xs')
    end.
End MapOpt.

Section MonadOperations.
  Context {T : Type -> Type} {M : Monad T}.
  Context {A B} (f : A -> T B).
  Fixpoint monad_map (l : list A)
    : T (list B)
    := match l with
       | nil => ret nil
       | x :: l => x' <- f x ;;
                  l' <- monad_map l ;;
                  ret (x' :: l')
       end.

  Definition monad_option_map (l : option A)
    : T (option B)
    := match l with
       | None => ret None
       | Some x => x' <- f x ;;
                   ret (Some x')
       end.

  Context (g : A -> B -> T A).
  Fixpoint monad_fold_left (l : list B) (x : A) : T A
    := match l with
       | nil => ret x
       | y :: l => x' <- g x y ;;
                   monad_fold_left l x'
       end.

  Fixpoint monad_fold_right (l : list B) (x : A) : T A
       := match l with
          | nil => ret x
          | y :: l => l' <- monad_fold_right l x ;;
                      g l' y
          end.

  Context (h : nat -> A -> T B).
  Fixpoint monad_map_i_aux (n0 : nat) (l : list A) : T (list B)
    := match l with
       | nil => ret nil
       | x :: l => x' <- (h n0 x) ;;
                   l' <- (monad_map_i_aux (S n0) l) ;;
                   ret (x' :: l')
       end.

  Definition monad_map_i := @monad_map_i_aux 0.
End MonadOperations.

Section MonadOperations.
  Context {T} {M : Monad T} {E} {ME : MonadExc E T}.
  Context {A B C} (f : A -> B -> T C) (e : E).
  Fixpoint monad_map2 (l : list A) (l' : list B) : T (list C) :=
    match l, l' with
    | nil, nil => ret nil
    | x :: l, y :: l' =>
      x' <- f x y ;;
      xs' <- monad_map2 l l' ;;
      ret (x' :: xs')
    | _, _ => raise e
    end.
End MonadOperations.

Definition monad_iter {T : Type -> Type} {M A} (f : A -> T unit) (l : list A) : T unit
  := @monad_fold_left T M _ _ (fun _ => f) l tt.

Fixpoint monad_All {T : Type -> Type} {M : Monad T} {A} {P} (f : forall x, T (P x)) l : T (@All A P l) := match l with
   | [] => ret All_nil
   | a :: l => X <- f a ;;
              Y <- monad_All f l ;;
              ret (All_cons X Y)
   end.

Fixpoint monad_All2 {T : Type -> Type} {E} {M : Monad T} {M' : MonadExc E T} wrong_sizes
  {A B R} (f : forall x y, T (R x y)) l1 l2 : T (@All2 A B R l1 l2) :=
  match l1, l2 with
   | [], [] => ret All2_nil
   | a :: l1, b :: l2 => X <- f a b ;;
                        Y <- monad_All2 wrong_sizes f l1 l2 ;;
                        ret (All2_cons X Y)
   | _, _ => raise wrong_sizes
   end.

Definition monad_prod {T} {M : Monad T} {A B} (x : T A) (y : T B): T (A * B)%type
  := X <- x ;; Y <- y ;; ret (X, Y).


Definition check_dec {T : Type -> Type} {E : Type} {M : Monad T} {M' : MonadExc E T} (e : E) {P}
  (H : {P} + {~ P}) : T P
  := match H with
  | left x => ret x
  | right _ => raise e
  end.

Definition check_eq_true {T : Type -> Type} {E : Type} {M : Monad T} {M' : MonadExc E T} (b : bool) (e : E) : T b :=
  if b return T b then ret eq_refl else raise e.

Definition check_eq_nat {T : Type -> Type} {E : Type} {M : Monad T} {M' : MonadExc E T} n m (e : E) : T (n = m) :=
  match PeanoNat.Nat.eq_dec n m with
  | left p => ret p
  | right p => raise e
  end.

Program Fixpoint monad_Alli {T : Type -> Type} {M : Monad T} {A} {P} (f : forall n x, T (∥ P n x ∥)) l n
  : T (∥ @Alli A P n l ∥)
  := match l with
      | [] => ret (sq Alli_nil)
      | a :: l => X <- f n a ;;
                  Y <- monad_Alli f l (S n) ;;
                  ret _
      end.
Next Obligation.
  sq. constructor; assumption.
Defined.

Program Fixpoint monad_Alli_All {T : Type -> Type} {M : Monad T} {A} {P} {Q} (f : forall n x, ∥ Q x ∥ -> T (∥ P n x ∥)) l n :
  ∥ All Q l ∥ -> T (∥ @Alli A P n l ∥)
  := match l with
      | [] => fun _ => ret (sq Alli_nil)
      | a :: l => fun allq => X <- f n a _ ;;
                  Y <- monad_Alli_All f l (S n) _ ;;
                  ret _
      end.
Next Obligation. sq.
  now depelim allq.
Qed.
Next Obligation.
  sq; now depelim allq.
Qed.
Next Obligation.
  sq. constructor; assumption.
Defined.

Section monad_Alli_nth.
  Context {T} {M : Monad T} {A} {P : nat -> A -> Type}.
  Program Fixpoint monad_Alli_nth_gen l k
    (f : forall n x, nth_error l n = Some x -> T (∥ P (k + n) x ∥)) :
    T (∥ @Alli A P k l ∥)
    := match l with
      | [] => ret (sq Alli_nil)
      | a :: l => X <- f 0 a _ ;;
                  Y <- monad_Alli_nth_gen l (S k) (fun n x hnth => px <- f (S n) x hnth;; ret _) ;;
                  ret _
      end.
    Next Obligation.
      sq. now rewrite Nat.add_succ_r in px.
    Qed.
    Next Obligation.
      sq. rewrite Nat.add_0_r in X. constructor; auto.
    Qed.

  Definition monad_Alli_nth l (f : forall n x, nth_error l n = Some x -> T (∥ P n x ∥)) : T (∥ @Alli A P 0 l ∥) :=
    monad_Alli_nth_gen l 0 f.

End monad_Alli_nth.

Section MonadAllAll.
  Context {T : Type -> Type} {M : Monad T} {A} {P : A -> Type} {Q} (f : forall x, ∥ Q x ∥ -> T (∥ P x ∥)).
  Program Fixpoint monad_All_All l : ∥ All Q l ∥ -> T (∥ All P l ∥) :=
    match l returnAll Q l ∥ -> T (∥ All P l ∥) with
      | [] => fun _ => ret (sq All_nil)
      | a :: l => fun allq =>
      X <- f a _ ;;
      Y <- monad_All_All l _ ;;
      ret _
      end.
  Next Obligation. sq.
    now depelim allq.
  Qed.
  Next Obligation.
    sq; now depelim allq.
  Qed.
  Next Obligation.
    sq. constructor; assumption.
  Defined.
End MonadAllAll.

End monad_utils.

End MetaRocq_DOT_Utils_DOT_monad_utils_WRAPPED.
Module Export MetaRocq_DOT_Utils_DOT_monad_utils.
Module Export MetaRocq.
Module Export Utils.
Module monad_utils.
Include MetaRocq_DOT_Utils_DOT_monad_utils_WRAPPED.monad_utils.
End monad_utils.

End Utils.

End MetaRocq.

End MetaRocq_DOT_Utils_DOT_monad_utils.
Export Stdlib.Bool.Bool.
Export Stdlib.Lists.List.
Export MetaRocq.Utils.MRUtils.
Export MetaRocq.Utils.monad_utils.
Module Export MetaRocq_DOT_Utils_DOT_utils.
Module Export MetaRocq.
Module Export Utils.
Module Export utils.
End utils.

End Utils.

End MetaRocq.

End MetaRocq_DOT_Utils_DOT_utils.

Definition ident   := string.

Definition dirpath := list ident.

Module IdentOT := StringOT.

Module DirPathOT := ListOrderedType IdentOT.

Inductive modpath :=
| MPfile  (dp : dirpath)
| MPbound (dp : dirpath) (id : ident) (i : nat)
| MPdot   (mp : modpath) (id : ident).

Definition kername := modpath × ident.

Module Export ModPathComp.

  Definition mpbound_compare dp id k dp' id' k' :=
    compare_cont (DirPathOT.compare dp dp')
      (compare_cont (IdentOT.compare id id') (Nat.compare k k')).

  Fixpoint compare mp mp' :=
    match mp, mp' with
    | MPfile dp, MPfile dp' => DirPathOT.compare dp dp'
    | MPbound dp id k, MPbound dp' id' k' =>
      mpbound_compare dp id k dp' id' k'
    | MPdot mp id, MPdot mp' id' =>
      compare_cont (compare mp mp') (IdentOT.compare id id')
    | MPfile _, _ => Gt
    | _, MPfile _ => Lt
    | MPbound _ _ _, _ => Gt
    | _, MPbound _ _ _ => Lt
    end.

End ModPathComp.

  Definition compare kn kn' :=
    match kn, kn' with
    | (mp, id), (mp', id') =>
      compare_cont (ModPathComp.compare mp mp') (IdentOT.compare id id')
    end.

Module Kername.

  Definition eqb kn kn' :=
    match compare kn kn' with
    | Eq => true
    | _ => false
    end.

  #[global, program] Instance reflect_kername : ReflectEq kername := {
    eqb := eqb
  }.
Admit Obligations.

End Kername.

Notation eq_kername := (eqb (A:=kername)) (only parsing).

Record inductive : Set := mkInd { inductive_mind : kername ;
                                  inductive_ind : nat }.

Record projection := mkProjection
  { proj_ind : inductive;
    proj_npars : nat;
    proj_arg : nat  }.
Module Export Kernames.
End Kernames.

Inductive name : Set :=
| nAnon
| nNamed (_ : ident).

Inductive recursivity_kind :=
  | Finite
  | CoFinite
  | BiFinite .

Section Contexts.
End Contexts.

Section ContextMap.
End ContextMap.

Section ContextTest.
End ContextTest.

Section ContextTestK.
End ContextTestK.

Section Contexts.

End Contexts.

Section Contexts.

End Contexts.
Module Export MetaRocq_DOT_Common_DOT_BasicAst.
Module Export MetaRocq.
Module Export Common.
Module Export BasicAst.
End BasicAst.

End Common.

End MetaRocq.

End MetaRocq_DOT_Common_DOT_BasicAst.
  Section GeneralLemmas.

  End GeneralLemmas.

Inductive allowed_eliminations : Set :=
  | IntoSProp
  | IntoPropSProp
  | IntoSetPropSProp
  | IntoAny.

Section UnivCF2.

End UnivCF2.

Section UniverseLemmas.
End UniverseLemmas.

Section no_prop_leq_type.

End no_prop_leq_type.

Section Closedu.
End Closedu.

Section UniverseClosedSubst.

End UniverseClosedSubst.

Section SubstInstanceClosed.
End SubstInstanceClosed.
Module Export MetaRocq_DOT_Common_DOT_Universes.
Module Export MetaRocq.
Module Export Common.
Module Export Universes.
End Universes.

End Common.

End MetaRocq.

End MetaRocq_DOT_Common_DOT_Universes.
Variant prim_tag :=
  | primInt
  | primFloat
  | primString
  | primArray.
Module Export MetaRocq_DOT_Common_DOT_Primitive.
Module Export MetaRocq.
Module Export Common.
Module Export Primitive.
End Primitive.

End Common.

End MetaRocq.

End MetaRocq_DOT_Common_DOT_Primitive.
Module Type Term.
End Term.

Module Type TermDecide (Import T : Term).
End TermDecide.

Module TermDecideReflectInstances (Import T : Term) (Import TDec : TermDecide T).
End TermDecideReflectInstances.

Module Type EnvironmentSig (T : Term).
End EnvironmentSig.

Module Type EnvironmentDecide (T : Term) (Import E : EnvironmentSig T).
End EnvironmentDecide.

Module EnvironmentDecideReflectInstances (T : Term) (Import E : EnvironmentSig T) (Import EDec : EnvironmentDecide T E).
End EnvironmentDecideReflectInstances.

Module Type TermUtils (T: Term) (E: EnvironmentSig T).

End TermUtils.
Module Export MetaRocq.
Module Export Common.
Module Export Environment.
End Environment.

End Common.

End MetaRocq.
Import Stdlib.ssr.ssreflect.
Import Stdlib.ssr.ssrbool.
Import MetaRocq.Utils.utils.
Import MetaRocq.Common.BasicAst.
Import MetaRocq.Common.Universes.
Import MetaRocq.Common.Environment.
Import MetaRocq.Common.Primitive.

Module Lookup (T : Term) (E : EnvironmentSig T).

End Lookup.

Module Type LookupSig (T : Term) (E : EnvironmentSig T).
End LookupSig.

Module EnvTyping (T : Term) (E : EnvironmentSig T) (TU : TermUtils T E).

  Section TypeLocal.
  End TypeLocal.

  Section All_local_env_rel.

  End All_local_env_rel.

  Section TypeLocalOver.

  End TypeLocalOver.

  Section TypeCtxInst.
  End TypeCtxInst.

  Section lift_sorting_size_gen.

  End lift_sorting_size_gen.

  Section All_local_env_size.
  End All_local_env_size.

  Section Regular.
  End Regular.

  Section Bidirectional.
  End Bidirectional.

End EnvTyping.

Module Type EnvTypingSig (T : Term) (E : EnvironmentSig T) (TU : TermUtils T E).
End EnvTypingSig.

Module Conversion (T : Term) (E : EnvironmentSig T) (TU : TermUtils T E) (ET : EnvTypingSig T E TU).

  Section Conversion.
  End Conversion.
End Conversion.

Module Type ConversionSig (T : Term) (E : EnvironmentSig T) (TU : TermUtils T E) (ET : EnvTypingSig T E TU).
End ConversionSig.

Module GlobalMaps (T: Term) (E: EnvironmentSig T) (TU : TermUtils T E) (ET: EnvTypingSig T E TU) (C: ConversionSig T E TU ET) (L: LookupSig T E).

  End GlobalMaps.

  Section Properties.
  End Properties.
Import Stdlib.Unicode.Utf8.

Set Universe Polymorphism.

Section PrimModel.
  Universe i.
  Context {term : Type@{i}}.

  Record array_model : Type@{i} :=
  { array_default : term;
    array_value : list term }.

  Inductive prim_model : prim_tag -> Type@{i} :=
  | primIntModel (i : PrimInt63.int) : prim_model primInt
  | primFloatModel (f : PrimFloat.float) : prim_model primFloat
  | primStringModel (s : PrimString.string) : prim_model primString
  | primArrayModel (a : array_model) : prim_model primArray.
Definition prim_val : Type@{i}.
exact (∑ t : prim_tag, prim_model t).
Defined.

  Definition prim_int i : prim_val := (primInt; primIntModel i).
  Definition prim_float f : prim_val := (primFloat; primFloatModel f).
  Definition prim_string s : prim_val := (primString; primStringModel s).
  Definition prim_array a : prim_val := (primArray; primArrayModel a).
Definition test_prim (f : term -> bool) (p : prim_val) : bool.
admit.
Defined.
End PrimModel.
Arguments prim_val : clear implicits.

Section PrimOps.
  Universes i j.
  Context {term : Type@{i}} {term' : Type@{j}}.
Definition map_prim (f : term -> term') (p : prim_val term) : prim_val term'.
admit.
Defined.
End PrimOps.

Inductive All2_Set {A B : Set} (R : A -> B -> Set) : list A -> list B -> Set :=
  All2_nil : All2_Set R [] []
| All2_cons : forall (x : A) (y : B) (l : list A) (l' : list B),
    R x y -> All2_Set R l l' -> All2_Set R (x :: l) (y :: l').
Arguments All2_nil {_ _ _}.
Arguments All2_cons {_ _ _ _ _ _ _}.
Equations All2_over {A B : Set} {P : A → B → Set} {l : list A} {l' : list B} :
  All2_Set P l l' → (∀ (x : A) (y : B), P x y → Type) → Type :=
| All2_nil, _ := unit
| All2_cons rxy rll', Q => Q _ _ rxy × All2_over rll' Q.

  Section map_onPrims.
  End map_onPrims.
Module Export EAst.

Record def (term : Set) := { dname : name; dbody : term; rarg : nat }.
Arguments dname {term} d.
Arguments dbody {term} d.
Arguments rarg {term} d.

Definition map_def {term : Set} (f : term -> term) (d : def term) :=
  {| dname := d.(dname); dbody := f d.(dbody); rarg := d.(rarg) |}.

Definition test_def {term : Set} (f : term -> bool) (d : def term) :=
  f d.(dbody).

Definition mfixpoint (term : Set) := list (def term).

Inductive term : Set :=
| tBox
| tRel (n : nat)
| tVar (i : ident)
| tEvar (n : nat) (l : list term)
| tLambda (na : name) (t : term)
| tLetIn (na : name) (b t : term)
| tApp (u v : term)
| tConst (k : kername)
| tConstruct (ind : inductive) (n : nat) (args : list term)
| tCase (indn : inductive * nat ) (c : term  ) (brs : list (list name * term) )
| tProj (p : projection) (c : term)
| tFix (mfix : mfixpoint term) (idx : nat)
| tCoFix (mfix : mfixpoint term) (idx : nat)
| tPrim (prim : prim_val term)
| tLazy (t : term)
| tForce (t : term).

Fixpoint mkApps t us :=
  match us with
  | nil => t
  | a :: args => mkApps (tApp t a) args
  end.

Definition isLambda t :=
  match t with
  | tLambda _ _ => true
  | _ => false
  end.

Record constructor_body :=
  mkConstructor {
    cstr_name : ident;
    cstr_nargs : nat
  }.

Record projection_body :=
  mkProjection {
    proj_name : ident;
  }.

Record one_inductive_body : Set := {
  ind_name : ident;
  ind_propositional : bool;
  ind_kelim : allowed_eliminations;
  ind_ctors : list constructor_body;
  ind_projs : list projection_body  }.

Record mutual_inductive_body := {
  ind_finite : recursivity_kind;
  ind_npars : nat;
  ind_bodies : list one_inductive_body }.

Definition cstr_arity (mdecl : mutual_inductive_body) (cdecl : constructor_body) :=
  (mdecl.(ind_npars) + cdecl.(cstr_nargs))%nat.

Record constant_body := { cst_body : option term }.

Inductive global_decl :=
| ConstantDecl : constant_body -> global_decl
| InductiveDecl : mutual_inductive_body -> global_decl.

Definition global_declarations := list (kername * global_decl).

Notation global_context := global_declarations.
Module Export MetaRocq.
Module Export Erasure.
Module Export EAst.
End EAst.

Fixpoint decompose_app_rec t l :=
  match t with
  | tApp f a => decompose_app_rec f (a :: l)
  | f => (f, l)
  end.

Definition decompose_app f := decompose_app_rec f [].

Definition head t := fst (decompose_app t).

Definition isFix t :=
  match t with
  | tFix _ _ => true
  | _ => false
  end.

Definition isConstruct t :=
  match t with
  | tConstruct _ _ _ => true
  | _ => false
  end.

Definition isPrim t :=
  match t with
  | tPrim _ => true
  | _ => false
  end.

Definition isBox t :=
  match t with
  | tBox => true
  | _ => false
  end.

Definition isLazy c :=
  match c with
  | tLazy _ => true
  | _ => false
  end.

Definition isFixApp t := isFix (head t).
Definition isConstructApp t := isConstruct (head t).
Definition isPrimApp t := isPrim (head t).
Definition isLazyApp t := isLazy (head t).

Section PrimDeps.

End PrimDeps.

Section All_rec.
End All_rec.
Section MkApps_rec.

  End MkApps_rec.

  Section MkApps_case.

  End MkApps_case.
Module Export ELiftSubst.

Fixpoint lift n k t : term :=
  match t with
  | tRel i => if Nat.leb k i then tRel (n + i) else tRel i
  | tEvar ev args => tEvar ev (List.map (lift n k) args)
  | tLambda na M => tLambda na (lift n (S k) M)
  | tApp u v => tApp (lift n k u) (lift n k v)
  | tLetIn na b b' => tLetIn na (lift n k b) (lift n (S k) b')
  | tCase ind c brs =>
    let brs' := List.map (fun br =>
      (br.1, lift n (#|br.1| + k) br.2)) brs in
    tCase ind (lift n k c) brs'
  | tProj p c => tProj p (lift n k c)
  | tFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (lift n k')) mfix in
    tFix mfix' idx
  | tCoFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (lift n k')) mfix in
    tCoFix mfix' idx
  | tBox => t
  | tVar _ => t
  | tConst _ => t
  | tConstruct ind i args => tConstruct ind i (map (lift n k) args)
  | tPrim p => tPrim (map_prim (lift n k) p)
  | tLazy t => tLazy (lift n k t)
  | tForce t => tForce (lift n k t)
  end.

Notation lift0 n := (lift n 0).

Fixpoint subst s k u :=
  match u with
  | tRel n =>
    if Nat.leb k n then
      match nth_error s (n - k) with
      | Some b => lift0 k b
      | None => tRel (n - List.length s)
      end
    else tRel n
  | tEvar ev args => tEvar ev (List.map (subst s k) args)
  | tLambda na M => tLambda na (subst s (S k) M)
  | tApp u v => tApp (subst s k u) (subst s k v)
  | tLetIn na b b' => tLetIn na (subst s k b) (subst s (S k) b')
  | tCase ind c brs =>
    let brs' := List.map (fun br => (br.1, subst s (#|br.1| + k) br.2)) brs in
    tCase ind (subst s k c) brs'
  | tProj p c => tProj p (subst s k c)
  | tFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (subst s k')) mfix in
    tFix mfix' idx
  | tCoFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (subst s k')) mfix in
    tCoFix mfix' idx
  | tConstruct ind i args => tConstruct ind i (map (subst s k) args)
  | tPrim p => tPrim (map_pr

[...]

mutual_inductive_body := {
  ind_finite : recursivity_kind;
  ind_npars : nat;
  ind_bodies : list one_inductive_body }.

Definition cstr_arity (mdecl : mutual_inductive_body) (cdecl : constructor_body) :=
  (mdecl.(ind_npars) + cdecl.(cstr_nargs))%nat.

Record constant_body := { cst_body : option term }.

Inductive global_decl :=
| ConstantDecl : constant_body -> global_decl
| InductiveDecl : mutual_inductive_body -> global_decl.

Definition global_declarations := list (kername * global_decl).

Notation global_context := global_declarations.
Module Export MetaRocq.
Module Export Erasure.
Module Export EAst.
End EAst.

Fixpoint decompose_app_rec t l :=
  match t with
  | tApp f a => decompose_app_rec f (a :: l)
  | f => (f, l)
  end.

Definition decompose_app f := decompose_app_rec f [].

Definition head t := fst (decompose_app t).

Definition isFix t :=
  match t with
  | tFix _ _ => true
  | _ => false
  end.

Definition isConstruct t :=
  match t with
  | tConstruct _ _ _ => true
  | _ => false
  end.

Definition isPrim t :=
  match t with
  | tPrim _ => true
  | _ => false
  end.

Definition isBox t :=
  match t with
  | tBox => true
  | _ => false
  end.

Definition isLazy c :=
  match c with
  | tLazy _ => true
  | _ => false
  end.

Definition isFixApp t := isFix (head t).
Definition isConstructApp t := isConstruct (head t).
Definition isPrimApp t := isPrim (head t).
Definition isLazyApp t := isLazy (head t).

Section PrimDeps.

End PrimDeps.

Section All_rec.
End All_rec.
Section MkApps_rec.

  End MkApps_rec.

  Section MkApps_case.

  End MkApps_case.
Module Export ELiftSubst.

Fixpoint lift n k t : term :=
  match t with
  | tRel i => if Nat.leb k i then tRel (n + i) else tRel i
  | tEvar ev args => tEvar ev (List.map (lift n k) args)
  | tLambda na M => tLambda na (lift n (S k) M)
  | tApp u v => tApp (lift n k u) (lift n k v)
  | tLetIn na b b' => tLetIn na (lift n k b) (lift n (S k) b')
  | tCase ind c brs =>
    let brs' := List.map (fun br =>
      (br.1, lift n (#|br.1| + k) br.2)) brs in
    tCase ind (lift n k c) brs'
  | tProj p c => tProj p (lift n k c)
  | tFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (lift n k')) mfix in
    tFix mfix' idx
  | tCoFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (lift n k')) mfix in
    tCoFix mfix' idx
  | tBox => t
  | tVar _ => t
  | tConst _ => t
  | tConstruct ind i args => tConstruct ind i (map (lift n k) args)
  | tPrim p => tPrim (map_prim (lift n k) p)
  | tLazy t => tLazy (lift n k t)
  | tForce t => tForce (lift n k t)
  end.

Notation lift0 n := (lift n 0).

Fixpoint subst s k u :=
  match u with
  | tRel n =>
    if Nat.leb k n then
      match nth_error s (n - k) with
      | Some b => lift0 k b
      | None => tRel (n - List.length s)
      end
    else tRel n
  | tEvar ev args => tEvar ev (List.map (subst s k) args)
  | tLambda na M => tLambda na (subst s (S k) M)
  | tApp u v => tApp (subst s k u) (subst s k v)
  | tLetIn na b b' => tLetIn na (subst s k b) (subst s (S k) b')
  | tCase ind c brs =>
    let brs' := List.map (fun br => (br.1, subst s (#|br.1| + k) br.2)) brs in
    tCase ind (subst s k c) brs'
  | tProj p c => tProj p (subst s k c)
  | tFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (subst s k')) mfix in
    tFix mfix' idx
  | tCoFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (subst s k')) mfix in
    tCoFix mfix' idx
  | tConstruct ind i args => tConstruct ind i (map (subst s k) args)
  | tPrim p => tPrim (map_prim (subst s k) p)
  | tLazy t => tLazy (subst s k t)
  | tForce t => tForce (subst s k t)
  | tBox => tBox
  | tVar n => tVar n
  | tConst c => tConst c
  end.

Notation subst0 t := (subst t 0).

Fixpoint closedn k (t : term) : bool :=
  match t with
  | tRel i => Nat.ltb i k
  | tEvar ev args => List.forallb (closedn k) args
  | tLambda _ M => closedn (S k) M
  | tApp u v => closedn k u && closedn k v
  | tLetIn na b b' => closedn k b && closedn (S k) b'
  | tCase ind c brs =>
    let brs' := List.forallb (fun br => closedn (#|br.1| + k) br.2) brs in
    closedn k c && brs'
  | tProj p c => closedn k c
  | tFix mfix idx =>
    let k' := List.length mfix + k in
    List.forallb (test_def (closedn k')) mfix
  | tCoFix mfix idx =>
    let k' := List.length mfix + k in
    List.forallb (test_def (closedn k')) mfix
  | tConstruct ind i args => forallb (closedn k) args
  | tPrim p => test_prim (closedn k) p
  | tLazy t => closedn k t
  | tForce t => closedn k t
  | _ => true
  end.

Notation closed t := (closedn 0 t).

Lemma closedn_subst s k t :
  forallb (closedn k) s -> closedn (#|s| + k) t ->
  closedn k (subst0 s t).
Admitted.
Module Export ECSubst.

Fixpoint csubst t k u :=
  match u with
  | tBox => tBox
  | tRel n =>
     match Nat.compare k n with
    | Datatypes.Eq => t
    | Gt => tRel n
    | Lt => tRel (Nat.pred n)
    end
  | tEvar ev args => tEvar ev (List.map (csubst t k) args)
  | tLambda na M => tLambda na (csubst t (S k) M)
  | tApp u v => tApp (csubst t k u) (csubst t k v)
  | tLetIn na b b' => tLetIn na (csubst t k b) (csubst t (S k) b')
  | tCase ind c brs =>
    let brs' := List.map (fun br => (br.1, csubst t (#|br.1| + k) br.2)) brs in
    tCase ind (csubst t k c) brs'
  | tProj p c => tProj p (csubst t k c)
  | tFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (csubst t k')) mfix in
    tFix mfix' idx
  | tCoFix mfix idx =>
    let k' := List.length mfix + k in
    let mfix' := List.map (map_def (csubst t k')) mfix in
    tCoFix mfix' idx
  | tConstruct ind n args => tConstruct ind n (map (csubst t k) args)
  | tPrim p => tPrim (map_prim (csubst t k) p)
  | tLazy u => tLazy (csubst t k u)
  | tForce u => tForce (csubst t k u)
  | x => x
  end.

Definition substl defs body : term :=
  fold_left (fun bod term => csubst term 0 bod)
    defs body.

Lemma closed_subst t k u : closed t ->
    csubst t k u = subst [t] k u.
Admitted.

Lemma closed_substl ts k u :
  forallb (closedn 0) ts ->
  closedn (#|ts| + k) u ->
  closedn k (ECSubst.substl ts u).
Admitted.
Import MetaRocq.Erasure.EAst.
Import MRMonadNotation.

Fixpoint lookup_env (Σ : global_context) id : option global_decl :=
  match Σ with
  | nil => None
  | hd :: tl =>
    if eq_kername id hd.1 then Some hd.2
    else lookup_env tl id
  end.

Definition declared_constant (Σ : global_context) id decl : Prop :=
  lookup_env Σ id = Some (ConstantDecl decl).

Section Lookups.
  Context (Σ : global_declarations).

  Definition lookup_minductive kn : option mutual_inductive_body :=
    decl <- lookup_env Σ kn;;
    match decl with
    | ConstantDecl _ => None
    | InductiveDecl mdecl => ret mdecl
    end.

  Definition lookup_inductive kn : option (mutual_inductive_body * one_inductive_body) :=
    mdecl <- lookup_minductive (inductive_mind kn) ;;
    idecl <- nth_error mdecl.(ind_bodies) (inductive_ind kn) ;;
    ret (mdecl, idecl).

  Definition lookup_constructor kn c : option (mutual_inductive_body * one_inductive_body * constructor_body) :=
    '(mdecl, idecl) <- lookup_inductive kn ;;
    cdecl <- nth_error idecl.(ind_ctors) c ;;
    ret (mdecl, idecl, cdecl).

End Lookups.

Definition inductive_isprop_and_pars Σ ind :=
  '(mdecl, idecl) <- lookup_inductive Σ ind ;;
  ret (idecl.(ind_propositional), mdecl.(ind_npars)).

Definition constructor_isprop_pars_decl Σ ind c :=
  '(mdecl, idecl, cdecl) <- lookup_constructor Σ ind c ;;
  ret (idecl.(ind_propositional), mdecl.(ind_npars), cdecl).

Definition closed_decl (d : EAst.global_decl) :=
  match d with
  | EAst.ConstantDecl cb =>
    option_default (ELiftSubst.closedn 0) (EAst.cst_body cb) true
  | EAst.InductiveDecl _ => true
  end.

Definition closed_env (Σ : EAst.global_declarations) :=
  forallb (test_snd closed_decl) Σ.

Definition fix_subst (l : mfixpoint term) :=
  let fix aux n :=
      match n with
      | 0 => []
      | S n => tFix l n :: aux n
      end
  in aux (List.length l).

Definition cofix_subst (l : mfixpoint term) :=
  let fix aux n :=
      match n with
      | 0 => []
      | S n => tCoFix l n :: aux n
      end
  in aux (List.length l).

Definition cunfold_fix (mfix : mfixpoint term) (idx : nat) :=
  match List.nth_error mfix idx with
  | Some d =>
    Some (d.(rarg), substl (fix_subst mfix) d.(dbody))
  | None => None
  end.

Definition cunfold_cofix (mfix : mfixpoint term) (idx : nat) :=
  match List.nth_error mfix idx with
  | Some d =>
    Some (d.(rarg), substl (cofix_subst mfix) d.(dbody))
  | None => None
  end.

Definition iota_red npar args (br : list name * term) :=
  substl (List.rev (List.skipn npar args)) br.2.
Import MetaRocq.Erasure.EAst.

Class WcbvFlags := { with_prop_case : bool ; with_guarded_fix : bool ; with_constructor_as_block : bool }.

Definition atom `{wfl : WcbvFlags} Σ t :=
  match t with
  | tBox
  | tCoFix _ _
  | tLambda _ _
  | tLazy _
  | tFix _ _ => true
  | tConstruct ind c [] => negb with_constructor_as_block && isSome (lookup_constructor Σ ind c)
  | _ => false
  end.

Section Wcbv.
  Context {wfl : WcbvFlags}.
  Context (Σ : global_declarations).

  Variant eval_primitive {term term' : Set} (eval : term -> term' -> Set) : prim_val term -> prim_val term' -> Set :=
    | evalPrimInt i : eval_primitive eval (prim_int i) (prim_int i)
    | evalPrimFloat f : eval_primitive eval (prim_float f) (prim_float f)
    | evalPrimString s : eval_primitive eval (prim_string s) (prim_string s)
    | evalPrimArray v def v' def'
      (ev : All2_Set eval v v')
      (ed : eval def def') :
      let a := {| array_default := def; array_value := v |} in
      let a' := {| array_default := def'; array_value := v' |} in
      eval_primitive eval (prim_array a) (prim_array a').

  Variant eval_primitive_ind {term term' : Set} (eval : term -> term' -> Set) (P : forall x y, eval x y -> Type) : forall x y, eval_primitive eval x y -> Type :=
  | evalPrimIntDep i : eval_primitive_ind eval P (prim_int i) (prim_int i) (evalPrimInt eval i)
  | evalPrimFloatDep f : eval_primitive_ind eval P (prim_float f) (prim_float f) (evalPrimFloat eval f)
  | evalPrimStringDep s : eval_primitive_ind eval P (prim_string s) (prim_string s) (evalPrimString eval s)
  | evalPrimArrayDep v def v' def'
    (ev : All2_Set eval v v')
    (ed : eval def def') :
    All2_over ev P -> P _ _ ed ->
    let a := {| array_default := def; array_value := v |} in
    let a' := {| array_default := def'; array_value := v' |} in
    eval_primitive_ind eval P (prim_array a) (prim_array a') (evalPrimArray eval v def v' def' ev ed).

  Local Unset Elimination Schemes.

  Inductive eval : term -> term -> Set :=

  | eval_box a t t' :
      eval a tBox ->
      eval t t' ->
      eval (tApp a t) tBox

  | eval_beta f na b a a' res :
      eval f (tLambda na b) ->
      eval a a' ->
      eval (csubst a' 0 b) res ->
      eval (tApp f a) res

  | eval_zeta na b0 b0' b1 res :
      eval b0 b0' ->
      eval (csubst b0' 0 b1) res ->
      eval (tLetIn na b0 b1) res

  | eval_iota ind pars cdecl discr c args brs br res :
      with_constructor_as_block = false ->
      eval discr (mkApps (tConstruct ind c []) args) ->
      constructor_isprop_pars_decl Σ ind c = Some (false, pars, cdecl) ->
      nth_error brs c = Some br ->
      #|args| = pars + cdecl.(cstr_nargs) ->
      #|skipn pars args| = #|br.1| ->
      eval (iota_red pars args br) res ->
      eval (tCase (ind, pars) discr brs) res

  | eval_iota_block ind pars cdecl discr c args brs br res :
      with_constructor_as_block = true ->
      eval discr (tConstruct ind c args) ->
      constructor_isprop_pars_decl Σ ind c = Some (false, pars, cdecl) ->
      nth_error brs c = Some br ->
      #|args| = pars + cdecl.(cstr_nargs) ->
      #|skipn pars args| = #|br.1| ->
      eval (iota_red pars args br) res ->
      eval (tCase (ind, pars) discr brs) res

  | eval_iota_sing ind pars discr brs n f res :
      with_prop_case ->
      eval discr tBox ->
      inductive_isprop_and_pars Σ ind = Some (true, pars) ->
      brs = [ (n,f) ] ->
      eval (substl (repeat tBox #|n|) f) res ->
      eval (tCase (ind, pars) discr brs) res

  | eval_fix f mfix idx argsv a av fn res :
      forall guarded : with_guarded_fix,
      eval f (mkApps (tFix mfix idx) argsv) ->
      eval a av ->
      cunfold_fix mfix idx = Some (#|argsv|, fn) ->
      eval (tApp (mkApps fn argsv) av) res ->
      eval (tApp f a) res

  | eval_fix_value f mfix idx argsv a av narg fn :
      forall guarded : with_guarded_fix,
      eval f (mkApps (tFix mfix idx) argsv) ->
      eval a av ->
      cunfold_fix mfix idx = Some (narg, fn) ->
      (#|argsv| < narg) ->
      eval (tApp f a) (tApp (mkApps (tFix mfix idx) argsv) av)

  | eval_fix' f mfix idx a av fn res narg :
    forall unguarded : with_guarded_fix = false,
    eval f (tFix mfix idx) ->
    cunfold_fix mfix idx = Some (narg, fn) ->
    eval a av ->
    eval (tApp fn av) res ->
    eval (tApp f a) res

  | eval_cofix_case ip mfix idx args discr narg fn brs res :
      eval discr (mkApps (tCoFix mfix idx) args) ->
      cunfold_cofix mfix idx = Some (narg, fn) ->
      eval (tCase ip (mkApps fn args) brs) res ->
      eval (tCase ip discr brs) res

  | eval_cofix_proj p mfix idx args discr narg fn res :
      eval discr (mkApps (tCoFix mfix idx) args) ->
      cunfold_cofix mfix idx = Some (narg, fn) ->
      eval (tProj p (mkApps fn args)) res ->
      eval (tProj p discr) res

  | eval_delta c decl body (isdecl : declared_constant Σ c decl) res :
      decl.(cst_body) = Some body ->
      eval body res ->
      eval (tConst c) res

  | eval_proj p cdecl discr args a res :
      with_constructor_as_block = false ->
      eval discr (mkApps (tConstruct p.(proj_ind) 0 []) args) ->
      constructor_isprop_pars_decl Σ p.(proj_ind) 0 = Some (false, p.(proj_npars), cdecl) ->
      #|args| = p.(proj_npars) + cdecl.(cstr_nargs) ->
      nth_error args (p.(proj_npars) + p.(proj_arg)) = Some a ->
      eval a res ->
      eval (tProj p discr) res

  | eval_proj_block p cdecl discr args a res :
      with_constructor_as_block = true ->
      eval discr (tConstruct p.(proj_ind) 0 args) ->
      constructor_isprop_pars_decl Σ p.(proj_ind) 0 = Some (false, p.(proj_npars), cdecl) ->
      #|args| = p.(proj_npars) + cdecl.(cstr_nargs) ->
      nth_error args (p.(proj_npars) + p.(proj_arg)) = Some a ->
      eval a res ->
      eval (tProj p discr) res

  | eval_proj_prop p discr :
      with_prop_case ->
      eval discr tBox ->
      inductive_isprop_and_pars Σ p.(proj_ind) = Some (true, p.(proj_npars)) ->
      eval (tProj p discr) tBox

  | eval_construct ind c mdecl idecl cdecl f args a a' :
    with_constructor_as_block = false ->
    lookup_constructor Σ ind c = Some (mdecl, idecl, cdecl) ->
    eval f (mkApps (tConstruct ind c []) args) ->
    #|args| < cstr_arity mdecl cdecl ->
    eval a a' ->
    eval (tApp f a) (tApp (mkApps (tConstruct ind c []) args) a')

  | eval_construct_block ind c mdecl idecl cdecl args args' :
    with_constructor_as_block = true ->
    lookup_constructor Σ ind c = Some (mdecl, idecl, cdecl) ->
    #|args| = cstr_arity mdecl cdecl ->
    All2_Set eval args args' ->
    eval (tConstruct ind c args) (tConstruct ind c args')

  | eval_app_cong f f' a a' :
      eval f f' ->
      ~~ (isLambda f' || (if with_guarded_fix then isFixApp f' else isFix f') || isBox f' || isConstructApp f'
        || isPrimApp f' || isLazyApp f')  ->
      eval a a' ->
      eval (tApp f a) (tApp f' a')

  | eval_prim p p' :
    eval_primitive eval p p' ->
    eval (tPrim p) (tPrim p')

  | eval_force t v v' :
    eval t (tLazy v) ->
    eval v v' ->
    eval (tForce t) v'

  | eval_atom t : atom Σ t -> eval t t.

End Wcbv.
Section eval_rect.

  Variables (wfl : WcbvFlags) (Σ : global_declarations) (P : forall x y, eval Σ x y → Type).

  Lemma eval_rect :
    (∀ (a t t' : term) (e : eval Σ a tBox),
     P a tBox e
     → ∀ e0 : eval Σ t t',
         P t t' e0 → P (tApp a t) tBox (eval_box Σ a t t' e e0))
  → (∀ (f0 : term) (na : name) (b a a' res : term)
       (e : eval Σ f0 (tLambda na b)),
       P f0 (tLambda na b) e
       → ∀ e0 : eval Σ a a',
           P a a' e0
           → ∀ e1 : eval Σ (csubst a' 0 b) res,
               P (csubst a' 0 b) res e1
               → P (tApp f0 a) res (eval_beta Σ f0 na b a a' res e e0 e1))
    → (∀ (na : name) (b0 b0' b1 res : term) (e : eval Σ b0 b0'),
         P b0 b0' e
         → ∀ e0 : eval Σ (csubst b0' 0 b1) res,
             P (csubst b0' 0 b1) res e0
             → P (tLetIn na b0 b1) res (eval_zeta Σ na b0 b0' b1 res e e0))
      → (∀ (ind : inductive) (pars : nat) (cdecl : constructor_body)
           (discr : term) (c : nat) (args : list term)
           (brs : list (list name × term)) (br : list name × term)
           (res : term) (e : with_constructor_as_block = false)
           (e0 : eval Σ discr (mkApps (tConstruct ind c []) args)),
           P discr (mkApps (tConstruct ind c []) args) e0
           → ∀ (e1 : constructor_isprop_pars_decl Σ ind c =
                     Some (false, pars, cdecl)) (e2 :
                                                 nth_error brs c =
                                                 Some br)
               (e3 : #|args| = pars + cstr_nargs cdecl)
               (e4 : #|skipn pars args| = #|br.1|)
               (e5 : eval Σ (iota_red pars args br) res),
               P (iota_red pars args br) res e5
               → P (tCase (ind, pars) discr brs) res
                   (eval_iota Σ ind pars cdecl discr c args brs br res e e0
                      e1 e2 e3 e4 e5))
        → (∀ (ind : inductive) (pars : nat) (cdecl : constructor_body)
             (discr : term) (c : nat) (args : list term)
             (brs : list (list name × term)) (br : list name × term)
             (res : term) (e : with_constructor_as_block = true)
             (e0 : eval Σ discr (tConstruct ind c args)),
             P discr (tConstruct ind c args) e0
             → ∀ (e1 : constructor_isprop_pars_decl Σ ind c =
                       Some (false, pars, cdecl))
                 (e2 : nth_error brs c = Some br)
                 (e3 : #|args| = pars + cstr_nargs cdecl)
                 (e4 : #|skipn pars args| = #|br.1|)
                 (e5 : eval Σ (iota_red pars args br) res),
                 P (iota_red pars args br) res e5
                 → P (tCase (ind, pars) discr brs) res
                     (eval_iota_block Σ ind pars cdecl discr c args brs br
                        res e e0 e1 e2 e3 e4 e5))
          → (∀ (ind : inductive) (pars : nat) (discr : term)
               (brs : list (list name × term)) (n : list name)
               (f4 res : term) (i : with_prop_case)
               (e : eval Σ discr tBox),
               P discr tBox e
               → ∀ (e0 : inductive_isprop_and_pars Σ ind = Some (true, pars))
                   (e1 : brs = [(n, f4)]) (e2 : eval Σ
                                                 (substl
                                                 (repeat tBox #|n|) f4) res),
                   P (substl (repeat tBox #|n|) f4) res e2
                   → P (tCase (ind, pars) discr brs) res
                       (eval_iota_sing Σ ind pars discr brs n f4 res i e e0
                          e1 e2))
            → (∀ (f5 : term) (mfix : mfixpoint term)
                 (idx : nat) (argsv : list term) (a av fn res : term)
                 (guarded : with_guarded_fix) (e :
                                               eval Σ f5
                                                 (mkApps
                                                 (tFix mfix idx) argsv)),
                 P f5 (mkApps (tFix mfix idx) argsv) e
                 → ∀ e0 : eval Σ a av,
                     P a av e0
                     → ∀ (e1 : cunfold_fix mfix idx = Some (#|argsv|, fn))
                         (e2 : eval Σ (tApp (mkApps fn argsv) av) res),
                         P (tApp (mkApps fn argsv) av) res e2
                         → P (tApp f5 a) res
                             (eval_fix Σ f5 mfix idx argsv a av fn res
                                guarded e e0 e1 e2))
              → (∀ (f6 : term) (mfix : mfixpoint term)
                   (idx : nat) (argsv : list term)
                   (a av : term) (narg : nat) (fn : term)
                   (guarded : with_guarded_fix) (e :
                                                 eval Σ f6
                                                 (mkApps
                                                 (tFix mfix idx) argsv)),
                   P f6 (mkApps (tFix mfix idx) argsv) e
                   → ∀ e0 : eval Σ a av,
                       P a av e0
                       → ∀ (e1 : cunfold_fix mfix idx = Some (narg, fn))
                           (l : #|argsv| < narg),
                           P (tApp f6 a)
                             (tApp (mkApps (tFix mfix idx) argsv) av)
                             (eval_fix_value Σ f6 mfix idx argsv a av narg fn
                                guarded e e0 e1 l))
                → (∀ (f7 : term) (mfix : mfixpoint term)
                     (idx : nat) (a av fn res : term)
                     (narg : nat) (unguarded : with_guarded_fix = false)
                     (e : eval Σ f7 (tFix mfix idx)),
                     P f7 (tFix mfix idx) e
                     → ∀ (e0 : cunfold_fix mfix idx = Some (narg, fn))
                         (e1 : eval Σ a av),
                         P a av e1
                         → ∀ e2 : eval Σ (tApp fn av) res,
                             P (tApp fn av) res e2
                             → P (tApp f7 a) res
                                 (eval_fix' Σ f7 mfix idx a av fn res narg
                                    unguarded e e0 e1 e2))
                  → (∀ (ip : inductive × nat) (mfix : mfixpoint term)
                       (idx : nat) (args : list term)
                       (discr : term) (narg : nat)
                       (fn : term) (brs : list (list name × term))
                       (res : term) (e : eval Σ discr
                                           (mkApps (tCoFix mfix idx) args)),
                       P discr (mkApps (tCoFix mfix idx) args) e
                       → ∀ (e0 : cunfold_cofix mfix idx = Some (narg, fn))
                           (e1 : eval Σ (tCase ip (mkApps fn args) brs) res),
                           P (tCase ip (mkApps fn args) brs) res e1
                           → P (tCase ip discr brs) res
                               (eval_cofix_case Σ ip mfix idx args discr narg
                                  fn brs res e e0 e1))
                    → (∀ (p : projection) (mfix : mfixpoint term)
                         (idx : nat) (args : list term)
                         (discr : term) (narg : nat)
                         (fn res : term) (e : eval Σ discr
                                                (mkApps
                                                 (tCoFix mfix idx) args)),
                         P discr (mkApps (tCoFix mfix idx) args) e
                         → ∀ (e0 : cunfold_cofix mfix idx = Some (narg, fn))
                             (e1 : eval Σ (tProj p (mkApps fn args)) res),
                             P (tProj p (mkApps fn args)) res e1
                             → P (tProj p discr) res
                                 (eval_cofix_proj Σ p mfix idx args discr
                                    narg fn res e e0 e1))
                      → (∀ (c : kername) (decl : constant_body)
                           (body : term) (isdecl :
                                          declared_constant Σ c decl)
                           (res : term) (e : cst_body decl = Some body)
                           (e0 : eval Σ body res),
                           P body res e0
                           → P (tConst c) res
                               (eval_delta Σ c decl body isdecl res e e0))
                        → (∀ (p : projection) (cdecl : constructor_body)
                             (discr : term) (args : list term)
                             (a res : term) (e : with_constructor_as_block =
                                                 false)
                             (e0 : eval Σ discr
                                     (mkApps (tConstruct (proj_ind p) 0 [])
                                        args)),
                             P discr
                               (mkApps (tConstruct (proj_ind p) 0 []) args)
                               e0
                             → ∀ (e1 : constructor_isprop_pars_decl Σ
                                         (proj_ind p) 0 =
                                       Some (false, proj_npars p, cdecl))
                                 (e2 : #|args| =
                                       proj_npars p + cstr_nargs cdecl)
                                 (e3 : nth_error args
                                         (proj_npars p + proj_arg p) =
                                       Some a) (e4 : eval Σ a res),
                                 P a res e4
                                 → P (tProj p discr) res
                                     (eval_proj Σ p cdecl discr args a res e
                                        e0 e1 e2 e3 e4))
                          → (∀ (p : projection) (cdecl : constructor_body)
                               (discr : term) (args : list term)
                               (a res : term) (e :
                                               with_constructor_as_block =
                                               true)
                               (e0 : eval Σ discr
                                       (tConstruct (proj_ind p) 0 args)),
                               P discr (tConstruct (proj_ind p) 0 args) e0
                               → ∀ (e1 : constructor_isprop_pars_decl Σ
                                           (proj_ind p) 0 =
                                         Some (false, proj_npars p, cdecl))
                                   (e2 : #|args| =
                                         proj_npars p + cstr_nargs cdecl)
                                   (e3 : nth_error args
                                           (proj_npars p + proj_arg p) =
                                         Some a) (e4 : eval Σ a res),
                                   P a res e4
                                   → P (tProj p discr) res
                                       (eval_proj_block Σ p cdecl discr args
                                          a res e e0 e1 e2 e3 e4))
                            → (∀ (p : projection)
                                 (discr : term) (i : with_prop_case)
                                 (e : eval Σ discr tBox),
                                 P discr tBox e
                                 → ∀ e0 : inductive_isprop_and_pars Σ
                                            (proj_ind p) =
                                          Some (true, proj_npars p),
                                     P (tProj p discr) tBox
                                       (eval_proj_prop Σ p discr i e e0))
                              → (∀ (ind : inductive)
                                   (c : nat) (mdecl : mutual_inductive_body)
                                   (idecl : one_inductive_body)
                                   (cdecl : constructor_body)
                                   (f14 : term) (args : list term)
                                   (a a' : term) (e :
                                                 with_constructor_as_block =
                                                 false)
                                   (e0 : lookup_constructor Σ ind c =
                                         Some (mdecl, idecl, cdecl))
                                   (e1 : eval Σ f14
                                           (mkApps (tConstruct ind c []) args)),
                                   P f14 (mkApps (tConstruct ind c []) args)
                                     e1
                                   → ∀ (l : #|args| < cstr_arity mdecl cdecl)
                                       (e2 : eval Σ a a'),
                                       P a a' e2
                                       → P (tApp f14 a)
                                           (tApp
                                              (mkApps
                                                 (tConstruct ind c []) args)
                                              a')
                                           (eval_construct Σ ind c mdecl
                                              idecl cdecl f14 args a a' e e0
                                              e1 l e2))
                                → (∀ (ind : inductive)
                                     (c : nat) (mdecl : mutual_inductive_body)
                                     (idecl : one_inductive_body)
                                     (cdecl : constructor_body)
                                     (args args' :
                                      list term) (e :
                                                 with_constructor_as_block =
                                                 true)
                                     (e0 : lookup_constructor Σ ind c =
                                           Some (mdecl, idecl, cdecl))
                                     (e1 : #|args| = cstr_arity mdecl cdecl)
                                     (a : All2_Set (eval Σ) args args')
                                     (iha : All2_over a P),
                                     P (tConstruct ind c args)
                                       (tConstruct ind c args')
                                       (eval_construct_block Σ ind c mdecl
                                          idecl cdecl args args' e e0 e1 a))
                                  → (∀ (f16 f' a a' : term)
                                       (e : eval Σ f16 f'),
                                       P f16 f' e
                                       → ∀ (i : ~~
                                                (isLambda f'
                                                 ||
                                                 (if with_guarded_fix
                                                 then isFixApp f'
                                                 else isFix f') ||
                                                 isBox f'
                                                 ||
                                                 isConstructApp f'
                                                 || isPrimApp f' || isLazyApp f'))
                                           (e0 : eval Σ a a'),
                                           P a a' e0
                                           → P (tApp f16 a)
                                               (tApp f' a')
                                               (eval_app_cong Σ f16 f' a a' e
                                                 i e0)) ->

    (forall p p' (ev : eval_primitive (eval Σ) p p'),
      eval_primitive_ind _ P _ _ ev ->
      P (tPrim p) (tPrim p') (eval_prim _ _ _ ev)) ->
    (forall t t' v (ev1 : eval Σ t (tLazy t')) (ev2 : eval Σ t' v),
      P _ _ ev1 -> P _ _ ev2 ->
      P (tForce t) v (eval_force _ t t' v ev1 ev2))

    → (∀ (t : term) (i : atom Σ t),
          P t t (eval_atom Σ t i))
      → ∀ (t t0 : term) (e : eval Σ t t0),
          P t t0 e.
Admitted.
  Definition eval_ind := eval_rect.

End eval_rect.

#[register=no] Scheme eval_nondep := Minimality for eval Sort Prop.

Lemma closedn_mkApps k f args : closedn k (mkApps f args) = closedn k f && forallb (closedn k) args.
Admitted.

Lemma eval_closed {wfl : WcbvFlags} Σ :
  closed_env Σ ->
  forall t u, closed t -> eval Σ t u -> closed u.
Proof.
  move=> clΣ t u Hc ev.
move: Hc.
  induction ev; simpl in *; auto;
    (move/andP=> [/andP[Hc Hc'] Hc''] || move/andP=> [Hc Hc'] || move=>Hc); auto.
  -
 eapply IHev3.
rewrite ECSubst.closed_subst //.
auto.
    eapply closedn_subst; tea.
cbn.
rewrite andb_true_r.
auto.
cbn.
auto.
  -
 eapply IHev2.
    rewrite ECSubst.closed_subst; auto.
    eapply closedn_subst; tea.
cbn.
rewrite andb_true_r.
auto.
  -
 specialize (IHev1 Hc).
    move: IHev1; rewrite closedn_mkApps => /andP[] _ clargs.
    apply IHev2.
rewrite /iota_red.
    eapply closed_substl.
now rewrite forallb_rev forallb_skipn.
    len.
rewrite e4.
🛠️ Intermediate Coq File (useful for debugging if minimization did not go as far as you wanted)
🛠️ 📜 Intermediate Coq File log (useful for debugging if minimization did not go as far as you wanted)
📜 Build Log (contains the Coq error message) (truncated to last 8.0KiB; full 8.2MiB file on GitHub Actions Artifacts under build.log)
-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_lookup_constructor wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_constructor_isprop_pars_decl wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1502, characters 4-177:
Warning:
Use of the non-reference term extends_is_propositional wf ex in "using" clauses is deprecated
[non-reference-hint-using,deprecated,default]
File "./theories/EWcbvEval.v", line 1634, characters 17-19:
Error: The variable e4 was not found in the current environment.

Command exited with non-zero status 1
theories/EWcbvEval.vo (real: 14.79, user: 14.28, sys: 0.31, mem: 987088 ko)
make[3]: *** [Makefile.erasure:813: theories/EWcbvEval.vo] Error 1
make[3]: *** [theories/EWcbvEval.vo] Deleting file 'theories/EWcbvEval.glob'
make[2]: *** [Makefile.erasure:411: all] Error 2
make[2]: Leaving directory '/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/erasure'
make[1]: *** [Makefile:11: theory] Error 2
make[1]: Leaving directory '/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/erasure'
make: *** [Makefile:164: erasure] Error 2
+ code=2
+ printf '\n%s exit code: %s\n' metarocq 2
+ '[' metarocq '!=' stdlib_test ']'
+ echo 'Aggregating timing log...'
Aggregating timing log...
+ echo

+ tools/make-one-time-file.py --real metarocq.log
    Time |  Peak Mem | File Name                    
----------------------------------------------------
0m24.42s | 987088 ko | Total Time / Peak Mem        
----------------------------------------------------
0m14.79s | 987088 ko | EWcbvEval.vo                 
0m04.78s | 854620 ko | EArities.vo                  
0m02.72s | 924872 ko | Extraction.vo                
0m01.98s | 892076 ko | SafeTemplateChecker.vo       
0m00.08s |  18340 ko | .Makefile.safecheckerplugin.d
0m00.07s |  18540 ko | .Makefile.plugin.d           
+ '[' '' ']'
+ exit 2
/github/workspace/builds/coq /github/workspace
::endgroup::
📜 🔎 Minimization Log (truncated to last 8.0KiB; full 4.0MiB file on GitHub Actions Artifacts under bug.log)
in/coqc.orig" "-q" "-w" "-deprecated-native-compiler-option" "-native-compiler" "no" "-coqlib" "/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq//" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/utils/theories" "MetaRocq.Utils" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/common/theories" "MetaRocq.Common" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/pcuic/theories" "MetaRocq.PCUIC" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/safechecker-plugin/theories" "MetaRocq.SafeCheckerPlugin" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/template-pcuic/theories" "MetaRocq.TemplatePCUIC" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/template-rocq/theories" "MetaRocq.Template" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/safechecker/theories" "MetaRocq.SafeChecker" "-R" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/erasure/theories" "MetaRocq.Erasure" "-Q" "/github/workspace/cwd" "Top" "-Q" "/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Equations" "Equations" "-Q" "/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Ltac2" "Ltac2" "-Q" "/github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Stdlib" "Stdlib" "-I" "/github/workspace/builds/coq/coq-failing/_build_ci/metarocq/template-rocq" "-top" "Top.bug_01" "/tmp/tmp4z1b37vv/Top/bug_01.v" "-q"

The timeout for ('/github/workspace/builds/coq/coq-failing/_install_ci/bin/coqc.orig',) has been set to: 6

The timeout for ('/github/workspace/builds/coq/coq-passing/_install_ci/bin/coqc.orig',) has been set to: 6
�[92m
Inlining MetaRocq.Utils.monad_utils via Include, stripping Requires, re-adding admit tactic wrapper succeeded.�[0m
�[92m
Sanity check passed.�[0m

Now, I will attempt to add an admit tactic wrapper to this file...
�[92m
Admit tactic wrapper added.�[0m

Now, I will attempt to strip repeated newlines and trailing spaces from this file...
�[92m
Succeeded in stripping newlines and spaces.�[0m

Now, I will attempt to strip the comments from this file...
�[92m
Succeeded in stripping comments.�[0m

Now, I will attempt to factor out all of the [Require]s...
getting bug_01.v (/github/workspace/cwd/bug_01.v)
NOTE: The file bug_01.v is very new (1763510974, 0 seconds old), delaying until it's a bit older
/github/workspace/builds/coq/coq-failing/_install_ci/bin/coqc.orig -q -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/utils/theories MetaRocq.Utils -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/common/theories MetaRocq.Common -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/pcuic/theories MetaRocq.PCUIC -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/safechecker-plugin/theories MetaRocq.SafeCheckerPlugin -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/template-pcuic/theories MetaRocq.TemplatePCUIC -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/template-rocq/theories MetaRocq.Template -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/safechecker/theories MetaRocq.SafeChecker -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/erasure/theories MetaRocq.Erasure -Q /github/workspace/cwd Top -Q /github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Equations Equations -Q /github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Ltac2 Ltac2 -Q /github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Stdlib Stdlib -I /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/template-rocq -q -w -deprecated-native-compiler-option -native-compiler no -coqlib /github/workspace/builds/coq/coq-failing/_install_ci/lib/coq// -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/utils/theories MetaRocq.Utils -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/common/theories MetaRocq.Common -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/pcuic/theories MetaRocq.PCUIC -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/safechecker-plugin/theories MetaRocq.SafeCheckerPlugin -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/template-pcuic/theories MetaRocq.TemplatePCUIC -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/template-rocq/theories MetaRocq.Template -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/safechecker/theories MetaRocq.SafeChecker -R /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/erasure/theories MetaRocq.Erasure -Q /github/workspace/cwd Top -Q /github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Equations Equations -Q /github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Ltac2 Ltac2 -Q /github/workspace/builds/coq/coq-failing/_install_ci/lib/coq///user-contrib/Stdlib Stdlib -I /github/workspace/builds/coq/coq-failing/_build_ci/metarocq/template-rocq -top Top.bug_01 -o /tmp/bug_01.vo -dump-glob /tmp/bug_01.glob bug_01.v
Moving '/tmp/bug_01.glob' to 'bug_01.glob'
/github/workspace/builds/coq/coq-passing/_install_ci/bin/coqc.orig -q -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/utils/theories MetaRocq.Utils -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/common/theories MetaRocq.Common -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/pcuic/theories MetaRocq.PCUIC -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/safechecker-plugin/theories MetaRocq.SafeCheckerPlugin -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/template-pcuic/theories MetaRocq.TemplatePCUIC -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/template-rocq/theories MetaRocq.Template -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/safechecker/theories MetaRocq.SafeChecker -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/erasure/theories MetaRocq.Erasure -Q /github/workspace/cwd Top -Q /github/workspace/builds/coq/coq-passing/_install_ci/lib/coq///user-contrib/Equations Equations -Q /github/workspace/builds/coq/coq-passing/_install_ci/lib/coq///user-contrib/Ltac2 Ltac2 -Q /github/workspace/builds/coq/coq-passing/_install_ci/lib/coq///user-contrib/MetaRocq MetaRocq -Q /github/workspace/builds/coq/coq-passing/_install_ci/lib/coq///user-contrib/Stdlib Stdlib -I /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/template-rocq -q -w -deprecated-native-compiler-option -native-compiler no -coqlib /github/workspace/builds/coq/coq-passing/_install_ci/lib/coq// -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/utils/theories MetaRocq.Utils -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/common/theories MetaRocq.Common -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/pcuic/theories MetaRocq.PCUIC -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/safechecker-plugin/theories MetaRocq.SafeCheckerPlugin -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/template-pcuic/theories MetaRocq.TemplatePCUIC -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/template-rocq/theories MetaRocq.Template -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/safechecker/theories MetaRocq.SafeChecker -R /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/erasure/theories MetaRocq.Erasure -Q /github/workspace/cwd Top -Q /github/workspace/builds/coq/coq-passing/_install_ci/lib/coq///user-contrib/Equations Equations -Q /github/workspace/builds/coq/coq-passing/_install_ci/lib/coq///user-contrib/Ltac2 Ltac2 -Q /github/workspace/builds/coq/coq-passing/_install_ci/lib/coq///user-contrib/MetaRocq MetaRocq -Q /github/workspace/builds/coq/coq-passing/_install_ci/lib/coq///user-contrib/Stdlib Stdlib -I /github/workspace/builds/coq/coq-passing/_build_ci/metarocq/template-rocq -top Top.bug_01 -o /tmp/bug_01.vo -dump-glob /tmp/bug_01.glob bug_01.v
WARNING: Clobbering 'bug_01.glob' (1763510977.770273) from 'bug_01.v' (1763510974.6452644) despite failure of coqc
getting bug_01.glob (/github/workspace/cwd/bug_01.glob)

If you have any comments on your experience of the minimizer, please share them in a reply (possibly tagging @JasonGross).
If you believe there's a bug in the bug minimizer, please report it on the bug minimizer issue tracker.

@felixL-K felixL-K force-pushed the generalize_schemes_try_rebase branch from daa1773 to e257755 Compare December 1, 2025 18:32
@coqbot-app coqbot-app bot added needs: full CI The latest GitLab pipeline that ran was a light CI. Say "@coqbot run full ci" to get a full CI. and removed needs: rebase Should be rebased on the latest master to solve conflicts or have a newer CI run. labels Dec 1, 2025
@github-actions github-actions bot added the needs: rebase Should be rebased on the latest master to solve conflicts or have a newer CI run. label Dec 8, 2025
@felixL-K felixL-K force-pushed the generalize_schemes_try_rebase branch from b062970 to 72951dc Compare December 23, 2025 15:38
@coqbot-app coqbot-app bot removed the needs: rebase Should be rebased on the latest master to solve conflicts or have a newer CI run. label Dec 23, 2025
Copy link
Contributor

@thomas-lamiaux thomas-lamiaux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have much to say except that I do not think it is a good practice to make types more specific for instance by adding a bool here and there.
We want generic type we understand and that are not ad-hoc and instantiate them appropriately when needed.

Comment on lines +24 to +26
val declare_scheme : Libobject.locality -> Key.t -> (inductive * GlobRef.t) -> unit
val lookup_scheme : (string list * UnivGen.QualityOrSet.t option * bool) -> inductive -> GlobRef.t
val all_schemes : unit -> GlobRef.t Key.Map.t Indmap_env.t
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I understand the idea not to really on string, I am not sure whether it is any better to really on sth as ad-hoc as:

string list * UnivGen.QualityOrSet.t option * bool

What if we later want to differentiate regular definition from template polymorphic one ? Or any variant of that ?
Would we add one more boolean ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably prefer a string with a well-written function to compute it that can be easily extended rather than extending the type ? What do you think ?


type is_mutual = bool

type t = (string list * UnivGen.QualityOrSet.t option * is_mutual)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use a list of string and not just a String ?

with_context_set ctx (UnivGen.fresh_global_instance env sym_scheme)

let build_sym_involutive_scheme env handle ind =
let build_sym_involutive_scheme env handle ind _ =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what is the standard in Ocaml, but I personally think it is much better to add an eta-expansion when the function needs to be applied like fun x y _ -> f x y than to add an unnamed variable at the definition f x y _.
It is not the end of the world as build_sym_involutive_scheme is not exposed in the .mli file, but it still makes it harder to maintain the code as you don't get why there is an extra-variable until you find where it is applied

(* Scheme builders. [bool] = is_dep. [None] = silent failure. *)
type mutual_scheme_object_function =
Environ.env -> handle -> MutInd.t -> constr array Evd.in_ustate
Environ.env -> handle -> inductive list -> bool -> constr array Evd.in_ustate option
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think a boolean should be added here. This is too specific.
To me a function instantiate to true should be given as an argument when needed.
Why is there an addition of the type option ?

let is_declared_scheme_object key = Hashtbl.mem scheme_object_table key

let scheme_kind_name (key : _ scheme_kind) : string = key
let get_suff sch_type sch_sort =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please name this get_suffix or whatever it is supposed to mean.
suff really does not mean anything. It could be a typo for stuff for instance.

?suff:string ->
?deps:(Environ.env -> MutInd.t -> scheme_dependency list) ->
val declare_mutual_scheme_object : string list * UnivGen.QualityOrSet.t option ->
(Declarations.one_inductive_body option -> string) ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree

val all_schemes : unit -> Constant.t CString.Map.t Indmap_env.t
module Key : sig

type t = (string list * UnivGen.QualityOrSet.t option * bool)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And yet, you want to be able to distinguish SortPoly or Not.
A basic algebraic type would probably suffice

let sigma = Evd.emit_side_effects eff sigma in
Proofview.Unsafe.tclEVARS sigma

(* Scheme builders. [bool] = is_dep. [None] = silent failure. *)
Copy link
Contributor

@thomas-lamiaux thomas-lamiaux Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[None] = silent failure.

What do you mean ?

Comment on lines +62 to +63
| SchemeMutualDep of Names.MutInd.t * mutual scheme_kind * bool
| SchemeIndividualDep of inductive * individual scheme_kind * bool
Copy link
Contributor

@thomas-lamiaux thomas-lamiaux Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why add tabs ? (and Names. btw )

with Not_found -> CErrors.user_err Pp.(str "Mutually defined schemes should be recursive."))
| _ -> (failwith "do_mutual_scheme expects a non empty list of inductive types.")

(* TODO : redifine do_mutual_induction_scheme using do_mutual_scheme *)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

@thomas-lamiaux
Copy link
Contributor

@felixL-K just to be clear, they are many design choices possible. I am questioning a few one that have been made, but I am not saying to change it. It should only be changed if, after discussing with the others like @SkySkimmer, we agree that this one or that one is better.

@github-actions github-actions bot added the needs: rebase Should be rebased on the latest master to solve conflicts or have a newer CI run. label Jan 8, 2026
@tabareau tabareau modified the milestones: 9.2+rc1, 9.3+rc1 Jan 26, 2026
@coqbot-app
Copy link
Contributor

coqbot-app bot commented Feb 9, 2026

The "needs: rebase" label was set more than 30 days ago. If the PR is not rebased in 30 days, it will be automatically closed.

@coqbot-app coqbot-app bot added the stale This PR will be closed unless it is rebased. label Feb 9, 2026
@coqbot-app
Copy link
Contributor

coqbot-app bot commented Mar 11, 2026

This PR was not rebased after 30 days despite the warning, it is now closed.

@coqbot-app coqbot-app bot closed this Mar 11, 2026
@coqbot-app coqbot-app bot removed this from the 9.3+rc1 milestone Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind: enhancement Enhancement to an existing user-facing feature, tactic, etc. needs: changelog entry This should be documented in doc/changelog. needs: documentation Documentation was not added or updated. needs: full CI The latest GitLab pipeline that ran was a light CI. Say "@coqbot run full ci" to get a full CI. needs: progress Work in progress: awaiting action from the author. needs: rebase Should be rebased on the latest master to solve conflicts or have a newer CI run. stale This PR will be closed unless it is rebased.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants