(* Axiom unsquash_inj : forall k1 k2, unsquash k1 = unsquash k2 -> k1 = k2. Arguments unsquash_inj [k1 k2] _.  Axiom squash_surj : forall k, exists n, exists Fp, squash (n, Fp) = k.  Axiom unsquash_approx : forall k n Fp, unsquash k = (n, Fp) -> Fp = KI.fmap (approx n) Fp. Implicit Arguments unsquash_approx [k n Fp].  Axiom approx_approx1 : forall m n, approx n = approx n oo approx (m+n).  Axiom approx_approx2 : forall m n, approx n = approx (m+n) oo approx n. *)
End KNOT__COVARIANT_HERED_PROP_OTH.
Module Type KNOT_INPUT__COVARIANT_HERED_PROP.
Parameter F : functor.
End KNOT_INPUT__COVARIANT_HERED_PROP.
Module Type KNOT__COVARIANT_HERED_PROP.
Declare Module KI : KNOT_INPUT__COVARIANT_HERED_PROP.
Parameter knot : Type.
Parameter ageable_knot : ageable knot.
Existing Instance ageable_knot.
Parameter squash : (nat * F (pred knot)) -> knot.
Parameter unsquash : knot -> (nat * F (pred knot)).
Parameter approx : nat -> pred knot -> pred knot.

(* Specifications: *)
Axiom approx_spec : forall n p k,
approx n p k = (level k < n /\ p k).
Axiom squash_unsquash : forall x,
squash (unsquash x) = x.
Axiom unsquash_squash : forall n x',
unsquash (squash (n,x')) = (n, fmap F (approx n) x').
(* Definitions of the "ageable" operations *)
Axiom knot_level : forall (k:knot),
level k = fst (unsquash k).
Axiom knot_age1 : forall (k:knot),
age1 k =
match unsquash k with
| (O,_) => None
| (S n,x) => Some (squash (n,x))
end.
(* (* Convenience lemmas, provable from the above interface *)
Axiom unsquash_inj : forall k1 k2,
unsquash k1 = unsquash k2 ->
k1 = k2.