(* This file is distributed under the terms of the MIT License, also known as the X11 Licence.  A copy of this license is in the README file that accompanied the original distribution of this file.  Based on code written by: Brian Aydemir Arthur Charg\'eraud *)
(* ********************************************************************** *)
(** * Defining atoms *)
(** Atoms are structureless objects such that we can always generate one fresh from a finite collection.  Equality on atoms is [eq] and decidable.  We use Coq's module system to make abstract the implementation of atoms. *)
Module Type ATOM <: UsualDecidableType.
Parameter atom : Set.
Definition t := atom.
Parameter eq_dec : forall x y : atom, {x = y} + {x <> y}.
Parameter atom_fresh_for_list :
forall (xs : list t), {x : atom | ~ List.In x xs}.
Parameter fresh : list atom -> atom.
Parameter fresh_not_in : forall l, ~ In (fresh l) l.
Parameter nat_of : atom -> nat.
Hint Resolve eq_dec.
Include HasUsualEq <+ UsualIsEq <+ UsualIsEqOrig.
End ATOM.
(** The implementation of the above interface is hidden for documentation purposes. *)
Module Atom : ATOM.
(* begin hide *)
Definition atom := nat.
Definition t := atom.
Definition eq_dec := eq_nat_dec.

Lemma nat_list_max : forall (xs : list nat),
{ n : nat | forall x, List.In x xs -> x <= n }.