Parameter T : Type.
Instance Ts : Setoid T.
Parameter T_bot : T.
Parameter other : Type.
Parameter otherS : Setoid other.
End TY_FUNCTOR.
Module Type KNOT.
Declare Module TF:TY_FUNCTOR.
Parameter knot : Type.
Instance knotS : Setoid knot.
Definition koS : Setoid (knot * other) := @ProdSetoid knot knotS other otherS.
Definition predicate := Mor koS Ts.
Definition predS : Setoid predicate := MorSetoid koS Ts.
Definition natFS : Setoid (nat * F predicate) := @ProdSetoid nat (EqSetoid nat) (F predicate) (Fs predS).
Existing Instance koS.
Existing Instance predS.
Existing Instance natFS.
Parameter squash : Mor natFS knotS.
Parameter unsquash : Mor knotS natFS.
Definition level : Mor knotS (EqSetoid nat) := fstM oo unsquash.
Parameter approx : forall n:nat, Mor predS predS.

(* Specifications: *)
Axiom approx_spec : forall n p w, approx n p w ==
if (le_gt_dec n (level (fst w))) then T_bot else p w.
Axiom squash_unsquash : forall x, squash (unsquash x) == x.
Axiom unsquash_squash : forall n x', unsquash (squash (n,x')) == (n,fmap (approx n) x').
Definition knot_age1 (k:knot) : option knot :=
match unsquash k with
| (O,_) => None
| (S n,x) => Some (squash (n,x))
end.