(*In this section we implement finite partial functions (FPF) with type set defined at module ListSet.v.  A FPF is a set of pairs. Given that both (x,y1) and (x,y2) with y1 != y2 may belong to a set of pairs, not every set of pairs is a FPF. For this reason, the specifier should use function IsPARTFUNC to test whether a given set of pairs is a FPF or not. All the other functions (DOM, RAN and PARTFUNC) assume that this test has been performed, otherwise their results are usless.  If f is a FPF and (x,y) belongs to f, then -f applied to x yields y, -x belongs to the domain of f -y belongs to the range of f. *)
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*)

Lemma AddEq :
forall (a b : X) (y : Y) (f : set (X * Y)),
a <> b -> PARTFUNC f a = PARTFUNC (set_add XYeq_dec (b, y) f) a.