(* * Copyright (c) 2009-2011, Andrew Appel, Robert Dockins and Aquinas Hobor. * *)
Local Open Scope nat_scope.
Module Type KNOT_FULL_BASIC_INPUT.
Parameter F: MixVariantFunctor.functor.
End KNOT_FULL_BASIC_INPUT.
Module Type KNOT_FULL_SA_INPUT.
Declare Module KI: KNOT_FULL_BASIC_INPUT.
Parameter Join_F: forall A, Join (F A). Existing Instance Join_F.
Parameter paf_F : pafunctor F Join_F.
Parameter Perm_F: forall A, Perm_alg (F A).
Parameter Sep_F: forall A, Sep_alg (F A).
End KNOT_FULL_SA_INPUT.
Module Type KNOT_BASIC.
Declare Module KI:KNOT_FULL_BASIC_INPUT.
Parameter knot: Type.
Parameter ageable_knot : ageable knot.
Existing Instance ageable_knot.
Parameter predicate: Type.
Parameter squash : (nat * F predicate) -> knot.
Parameter unsquash : knot -> (nat * F predicate).
Parameter approx : nat -> predicate -> predicate.

(* Specifications: *)
Axiom squash_unsquash : forall k:knot, squash (unsquash k) = k.
Axiom unsquash_squash : forall (n:nat) (f:F predicate),
unsquash (squash (n,f)) = (n, fmap F (approx n) (approx n) f).
Axiom knot_age1 : forall k:knot,
age1 k =
match unsquash k with
| (O,_) => None
| (S n,x) => Some (squash (n,x))
end.
Axiom knot_level : forall k:knot,
level k = fst (unsquash k).