(**************************************************************)
(*   Copyright Dominique Larchey-Wendling [*]                 *)
(*                                                            *)
(*                             [*] Affiliation LORIA -- CNRS  *)
(**************************************************************)
(*      This file is distributed under the terms of the       *)
(*         CeCILL v2 FREE SOFTWARE LICENSE AGREEMENT          *)
(**************************************************************)
(* ** Reification for bounded quantification *)
Set Implicit Arguments.
(* A nat indexed finite number of conjunctions *)
Definition fmap_reifier_t X (Q : nat -> X -> Prop) k :
(forall i, i < k -> sig (Q i))
-> { f : forall i, i < k -> X | forall i Hi, Q i (f i Hi) }.
Proof with try lia.
intros [ u ].
revert P; induction n as [ | n IHn ]; intros P HP.
+ exists (fun _ => u); intros...
+ destruct (IHn (fun i => P (S i))) as (f & Hf).
{ intros; apply HP... }
destruct (HP 0) as (x & Hx)...
exists (fun i => match i with 0 => x | S i => f i end).
intros [|] ?; auto; apply Hf...
Qed.
(* equal_upto m f g means f 0 = g 0, ... f (m-1) = g (m-1) *)
Local Notation equal_upto := (fun m (f g : nat -> nat) => forall n, n < m -> f n = g n).
(* Given a predicate P over nat * (nat -> nat), which is supposed to be finitary  1/ for any x, P x only takes the first p values of its argument into acounts 2/ P x is satisfiable for any value of x lower than n  then there is a bound m such that for any x, there is always a solution f to P x f which is uniformly bounded by m  *)

Theorem fmmap_reifer_bound p n (P : nat -> (nat -> nat) -> Prop) :
(forall x f g, equal_upto p f g -> P x f -> P x g)
-> (forall x, x < n -> exists f, P x f)
-> exists m f, forall x, x < n -> (forall j, j < p -> f x j < m) /\ P x (f x).