(************************************************************************)
(* Copyright 2007 Milad Niqui                                           *)
(* This file is distributed under the terms of the                      *)
(* GNU Lesser General Public License Version 2.1                        *)
(* A copy of the license can be found at                                *)
(*                  <http://www.gnu.org/licenses/lgpl.txt>              *)
(************************************************************************)
Require OrderedTypeEx.
Require FSetList.
Module NatSet := FSetList.Make(OrderedTypeEx.Nat_as_OT).
Infix "++" := add (at level 60, right associativity).
Notation "s [=] t" := (Equal s t) (at level 70, no associativity).
Require FSetFacts FSetProperties.
Require Extraction.
Module GeneralProperties := FSetProperties.Properties NatSet.
Section problem_knows_not_refl.
Variable town: t.
Variable n:nat.
Variable cardinality: cardinal town = 2*n+1.
Variable knows: elt -> elt -> Prop.
Variable knows_sym: forall m n, knows m n ->  knows n m.
Variable knows_extensional:forall m n p, E.eq n p -> knows m n-> knows m p.
Variable property: forall B, Subset B town -> cardinal B = n ->
{d:elt | In d (diff town B)/\(forall b, In b B -> knows d b)}.

(** The following property, proven by induction, is the heart of the solution, and is due to Tonny Hurkens. *)
Lemma inductive_invariant:forall m, m<= n ->
{B':t| Subset B' town /\ cardinal B' = m /\ forall b'0 b'1, In b'0 B' -> In b'1 B' -> ~(E.eq b'0 b'1) -> knows b'0 b'1}.