(************************************************************************)
(*         *      The Rocq Prover / The Rocq Development Team           *)
(*  v      *         Copyright INRIA, CNRS and contributors             *)
(* <O___,, * (see version control and CREDITS file for authors & dates) *)
(*   \VV/  **************************************************************)
(*    //   *    This file is distributed under the terms of the         *)
(*         *     GNU Lesser General Public License Version 2.1          *)
(*         *     (see LICENSE file for the text of the license)         *)
(************************************************************************)
Require Export List.
Require Export Sorted.
Require Export Setoid Basics Morphisms.
Set Implicit Arguments.
Unset Strict Implicit.
(* Set Universe Polymorphism. *)
(** * Logical relations over lists with respect to a setoid equality or ordering. *)
(** This can be seen as a complement of predicate [lelistA] and [sort] found in [Sorting]. *)
Section Type_with_equality.
Variable A : Type.
Variable eqA : A -> A -> Prop.
(** Being in a list modulo an equality relation over type [A]. *)
Inductive InA (x : A) : list A -> Prop :=
| InA_cons_hd : forall y l, eqA x y -> InA x (y :: l)
| InA_cons_tl : forall y l, InA x l -> InA x (y :: l).
#[local]
Hint Constructors InA : core.
(** TODO: it would be nice to have a generic definition instead of the previous one. Having [InA = Exists eqA] raises too many compatibility issues. For now, we only state the equivalence: *)

(* Specifications: *)
Lemma InA_altdef : forall x l, InA x l <-> Exists (eqA x) l.
Lemma InA_nil : forall x, InA x nil <-> False.
(** An alternative definition of [InA]. *)
Lemma InA_alt : forall x l, InA x l <-> exists y, eqA x y /\ In y l.
Inductive NoDupA : list A -> Prop :=
| NoDupA_nil : NoDupA nil
| NoDupA_cons : forall x l, ~ InA x l -> NoDupA l -> NoDupA (x::l).