Section discrete_quotient.
(* We show the FO bisimilarity/indistinguishability ≡ is both decidable and first order definable, ie there is a FO formula A(.,.) such that  x ≡ y <-> A(x,y) holds for any x,y in the model M  We use it to quotient the model M and get a discrete model (based on the finite type pos n) where identity coincides with FO bisimilarity.  The idea of the construction is the following. We start from a finitary signature Σ to simplify the explanation but the devel below works in a sub-signature of Σ where the list ls bounds usable terms symbols and the list lr usable bound relations symbols.  So given a finitary Σ and a finite and Boolean model M for Σ, we define the operator  F : (M² -> Prop) -> (M² -> Prop)  transforming a binary relation R : M² -> Prop into F(R).  x F(R) y iff      t(x)  R  t(y) for any t(.) = s<v(./p)> and f(x) <-> f(y) for any f(.) = r<v(./p)>  Then F(.) is monotonic, ω-continuous, and satisfies I ⊆ F(I), (F(R))⁻ ⊆ F(R⁻) and F(R) o F(R) ⊆ F (R o R) hence Kleene's greatest fixpoint gfp(F) exists, is obtained after ω-steps and is an equivalence relation.  Moreover, F preserves decidability and FO-definability. Now we show that gfp(F) ~ F^n(TT) for a finite n which implies that gfp(F) is decidable and FO-definable. Here TT := fun _ _ => True is the full binary relation over M.  The sequence n => F^n(TT) is a sequence of decidable (hence also weakly decidable) relations. If F^a(TT) ⊆ F^b(TT) for a < b then we have F^a(TT) ~ F^i(TT) for any i => a and thus for any i >= a F^i(TT) ~ gfp F.  The sequence n => F^n(TT) belongs to the weak power list of binary relations over M (upto equivalence) which contains all weakly decidable binary relations over M. By the PHP, for n greater that the length of this list (which is 2^(m*m) where m is the cardinal of M), we must have F^a(TT) ~ F^b(TT) for a <> b, hence we deduce F^n(TT) ~ gfp F.  Hence, gfp F is decidable and FO-definable as well.  *)
Variables (Σ : fo_signature) (ls : list (syms Σ)) (lr : list (rels Σ)).
(* fo_bisimilar means no FO formula can distinguish x from y. Beware that two free variables might be needed, see the remarks and counter-example below *)
Definition fo_bisimilar X M x y :=
forall A φ, incl (fol_syms A) ls
-> incl (fol_rels A) lr
-> @fol_sem Σ X M x·φ A <-> fol_sem M y·φ A.
(* Let us assume a finite and Boolean model m *)
Variables (X : Type)
(fin : finite_t X)
(M : fo_model Σ X)
(dec : fo_model_dec M).
Implicit Type (R T : X -> X -> Prop).
(* Construction of the greatest fixpoint of the following operator fom_op. Any prefixpoint R ⊆ fom_op R is a simulation for the model *)
Local Definition fom_op1 R x y := forall s, In s ls
-> forall (v : vec _ (ar_syms Σ s)) p,
R (fom_syms M s (v[x/p])) (fom_syms M s (v[y/p])).
Local Definition fom_op2 x y :=   forall s, In s lr
-> forall (v : vec _ (ar_rels Σ s)) p,
fom_rels M s (v[x/p]) <-> fom_rels M s (v[y/p]).
Local Definition fom_op R x y := fom_op1 R x y /\ fom_op2 x y.
(* First we show properties of fom_op  a) Monotonicity b) preserves Reflexivity, Symmetry and Transitivity c) ω-continuous d) preserves decidability e) preserves FO definability  *)
Hint Resolve finite_t_pos finite_t_vec : core.
(* Monotonicity *)
Local Fact fom_op_mono R T : (forall x y, R x y -> T x y) -> (forall x y, fom_op R x y -> fom_op T x y).
(* ω-continuity *)
Local Fact fom_op_continuous : gfp_continuous fom_op.
(* Decidability, a bit more complicated but we have all the tools to do it in an efficient way *)
Let fom_op1_dec R : (forall x y, { R x y } + { ~ R x y })
-> (forall x y, { fom_op1 R x y } + { ~ fom_op1 R x y }).
Let fom_op2_dec : (forall x y, { fom_op2 x y } + { ~ fom_op2 x y }).
Local Fact fom_op_dec R : (forall x y, { R x y } + { ~ R x y })
-> (forall x y, { fom_op R x y } + { ~ fom_op R x y }).
Let fol_def_fom_op2 : fol_definable ls lr M (fun ψ => fom_op2 (ψ 0) (ψ 1)).
Let fol_def_fom_op R : fol_definable ls lr M (fun ψ => R (ψ 0) (ψ 1))
-> fol_definable ls lr M (fun ψ => fom_op R (ψ 0) (ψ 1)).
Local Fact fo_bisimilar_fom_eq x y : fo_bisimilar M x y -> x ≡ y.

Theorem fom_eq_fol_characterization x y :
x ≡ y <-> fo_bisimilar M x y.