Section PartialFunctions.
Variable X Y : Set.
Hypothesis Xeq_dec : forall x1 x2 : X, {x1 = x2} + {x1 <> x2}.
Hypothesis Yeq_dec : forall x1 x2 : Y, {x1 = x2} + {x1 <> x2}.
Hypothesis XYeq_dec : forall x1 x2 : X * Y, {x1 = x2} + {x1 <> x2}.
(*Domain of a FPF*)
Fixpoint DOM (f : set (X * Y)) : set X :=
match f with
| nil => nil (A:=X)
| (x, y) :: g => set_add Xeq_dec x (DOM g)
end.
(*Range of a FPF*)
Fixpoint RAN (f : set (X * Y)) : set Y :=
match f with
| nil => nil (A:=Y)
| (x, y) :: g => set_add Yeq_dec y (RAN g)
end.
(*Application of a FPF*)
Fixpoint PARTFUNC (f : set (X * Y)) : X -> Exc Y :=
fun x : X =>
match f with
| nil => None (A:=Y)
| (x1, y) :: g =>
match Xeq_dec x x1 with
| left _ => Some y
| right _ => PARTFUNC g x
end
end.
(*Test to decide whether a set of pairs is a FPF or not*)
Fixpoint IsPARTFUNC (f : set (X * Y)) : Prop :=
match f with
| nil => True
| a :: l =>
match set_In_dec Xeq_dec (fst a) (DOM l) with
| left _ => False
| right _ => IsPARTFUNC l
end
end.
(*Some usefull lemmas about our implementation of FPF*)
intros.
induction  f as [| a0 f Hrecf].
simpl in |- *.
elim (Xeq_dec a b).
intros.
cut False.
intro.
elim H0.
unfold not in H; apply H.
auto.
auto.
simpl in |- *.
elim a0.
intros.
elim (Xeq_dec a a1).
elim (XYeq_dec (b, y) (a1, b0)).
intros.
cut False.
intro F.
elim F.
unfold not in H.
apply H.
rewrite a3.
injection a2.
auto.
simpl in |- *.
elim (Xeq_dec a a1).
auto.
intros.
cut False.
intro F.
elim F.
auto.
elim (XYeq_dec (b, y) (a1, b0)).
simpl in |- *.
elim (Xeq_dec a a1).
intros.
cut False.
intro F.
elim F.
auto.
auto.
simpl in |- *.
elim (Xeq_dec a a1).
intros.
cut False.
intro F.
elim F.
auto.
intros.
auto.
Qed.
simple induction f.
simpl in |- *.
elim (Xeq_dec x x); auto.
intro; absurd (x = x); auto.
simpl in |- *.
intros until l.
elim a.
intros until b.
elim (XYeq_dec (x, y) (a0, b)).
simpl in |- *.
elim (Xeq_dec x a0).
intros.
injection a2; intros.
rewrite H1; auto.
intros.
injection a1; intros; absurd (x = a0); auto.
simpl in |- *.
elim (Xeq_dec x a0).
intros.
rewrite a1 in H0.
cut False.
tauto.
apply H0.
apply set_add_intro2; auto.
intros.
apply H.
intro; apply H0; apply set_add_intro1; auto.
Qed.
intros.
induction  f as [| a0 f Hrecf].
auto.
simpl in |- *.
elim a0.
intros.
elim (Xeq_dec a a1).
elim (XYeq_dec (b, y) (a1, b0)).
intros.
cut False.
intro F.
elim F.
unfold not in H.
apply H.
rewrite a3.
injection a2.
auto.
simpl in |- *.
elim (Xeq_dec a a1).
auto.
intros.
cut False.
intro F.
elim F.
auto.
elim (XYeq_dec (b, y) (a1, b0)).
simpl in |- *.
elim (Xeq_dec a a1).
intros.
cut False.
intro F.
elim F.
auto.
auto.
simpl in |- *.
elim (Xeq_dec a a1).
intros.
cut False.
intro F.
elim F.
auto.
intros.
auto.
Qed.
intros.
induction  f as [| a0 f Hrecf].
simpl in |- *.
elim (Xeq_dec a b).
intros.
cut False.
intro F; elim F.
auto.
auto.
simpl in |- *.
elim a0.
intros.
elim (Xeq_dec a a1).
elim (XYeq_dec (b, y) (a1, b0)).
intros.
cut False.
intro F; elim F.
unfold not in H; apply H.
rewrite a3.
injection a2.
auto.
simpl in |- *.
elim (XYeq_dec (b, z) (a1, b0)).
intros.
cut False.
intro F; elim F.
unfold not in H.
apply H.
rewrite a3.
injection a2.
auto.
simpl in |- *.
elim (Xeq_dec a a1).
auto.
intros.
cut False.
intro F; elim F.
auto.
elim (XYeq_dec (b, y) (a1, b0)).
auto.
intros.
simpl in |- *.
elim (XYeq_dec (b, z) (a1, b0)).
simpl in |- *.
elim (Xeq_dec a a1).
intros.
cut False.
intro F; elim F.
auto.
intros.
apply RemEq.
auto.
auto.
simpl in |- *.
elim (Xeq_dec a a1).
intros.
cut False.
intro F; elim F.
auto.
auto.
Qed.
intros.
induction  f as [| a f Hrecf].
simpl in |- *.
auto.
generalize H.
simpl in |- *.
elim a.
intro; intro.
elim (Xeq_dec o a0).
intro.
rewrite a1.
intro.
cut False.
intro F; elim F.
unfold not in H0.
apply H0.
apply set_add_intro2.
auto.
intros.
apply Hrecf.
unfold not in H0; unfold not in |- *.
intro; apply H0.
apply set_add_intro1.
auto.
Qed.
Hint Resolve NotInDOMIsUndef.
simple induction f.
auto.
simpl in |- *.
intro.
elim a.
intro.
elim (Xeq_dec o a0).
intros; intro H3; discriminate H3.
intros; apply H.
eauto.
Qed.
intros; induction  f as [| a f Hrecf].
simpl in |- *.
left; auto.
simpl in |- *.
elim (XYeq_dec (x, y) a).
simpl in |- *.
elim a.
intros.
injection a1; intros.
apply set_add_intro2; auto.
simpl in |- *.
elim a.
intros.
apply set_add_intro1; auto.
Qed.
simple induction f.
simpl in |- *; auto.
simpl in |- *.
intro; elim a0.
intros until b; elim (XYeq_dec a (a1, b)).
elim a.
intros.
injection a3; intros.
simpl in H0; rewrite H2 in H0.
cut False.
tauto.
apply H0; apply set_add_intro2; auto.
elim a.
simpl in |- *.
intros.
cut (l = set_remove XYeq_dec (a2, b0) l).
intro.
rewrite <- H1; auto.
apply H.
intro; apply H0; apply set_add_intro; auto.
Qed.
Hint Resolve DOMFuncRel.
simple induction f.
simpl in |- *; auto.
simpl in |- *.
intro; elim a.
elim z.
simpl in |- *.
intros.
elim H0; intro.
injection H1; intros.
apply set_add_intro; auto.
cut (set_In a0 (DOM l)).
intro; apply set_add_intro1; auto.
auto.
Qed.
Hint Resolve DOMFuncRel2.
simple induction f.
simpl in |- *; auto.
simpl in |- *.
intros until l; elim (set_In_dec Xeq_dec (fst a) (DOM l));
elim (XYeq_dec (x, y) a).
tauto.
tauto.
intros; cut (l = set_remove XYeq_dec (x, y) l).
intro H2; rewrite <- H2; replace x with (fst a); auto.
rewrite <- a0; auto.
rewrite a0; auto.
simpl in |- *.
elim a.
simpl in |- *.
intros.
elim H1; intro.
absurd ((a0, b) = (x, y)); auto.
elim (Xeq_dec x a0); intro.
rewrite <- a1 in b1.
intro; apply b1; replace x with (fst (x, y)); auto.
cut (~ set_In x (DOM (set_remove XYeq_dec (x, y) l))).
auto.
auto.
Qed.
simple induction f.
simpl in |- *; auto.
simpl in |- *.
intros until l; elim a.
intros until b; elim (Xeq_dec x a0).
elim (PARTFUNC l x).
intros y2 H; left; rewrite H; auto.
intros H H1; left; rewrite H; auto.
elim (PARTFUNC l x).
auto.
auto.
Qed.

Lemma UndefWhenRem :
forall (x : X) (y : Y) (f : set (X * Y)),
IsPARTFUNC f ->
set_In (x, y) f -> PARTFUNC (set_remove XYeq_dec (x, y) f) x = None.