Class Input: Type := {
  knot: Type;
  Fpred: Type;
  squash: nat * Fpred -> knot;
  unsquash: knot -> nat * Fpred;
  approxF: nat -> Fpred -> Fpred;
  squash_unsquash : forall k:knot, squash (unsquash k) = k;
  unsquash_squash : forall (n:nat) (f:Fpred),
    unsquash (squash (n,f)) = (n, approxF n f)
}.Class Input: Type := {
  knot: Type;
  Fpred: Type;
  squash: nat * Fpred -> knot;
  unsquash: knot -> nat * Fpred;
  approxF: nat -> Fpred -> Fpred;
  squash_unsquash : forall k:knot, squash (unsquash k) = k;
  unsquash_squash : forall (n:nat) (f:Fpred),
    unsquash (squash (n,f)) = (n, approxF n f)
}.Class Input: Type := {
  knot: Type;
  Fpred: Type;
  squash: nat * Fpred -> knot;
  unsquash: knot -> nat * Fpred;
  approxF: nat -> Fpred -> Fpred;
  squash_unsquash : forall k:knot, squash (unsquash k) = k;
  unsquash_squash : forall (n:nat) (f:Fpred),
    unsquash (squash (n,f)) = (n, approxF n f)
}.Class Input: Type := {
  knot: Type;
  Fpred: Type;
  squash: nat * Fpred -> knot;
  unsquash: knot -> nat * Fpred;
  approxF: nat -> Fpred -> Fpred;
  squash_unsquash : forall k:knot, squash (unsquash k) = k;
  unsquash_squash : forall (n:nat) (f:Fpred),
    unsquash (squash (n,f)) = (n, approxF n f)
}.Class Input: Type := {
  knot: Type;
  Fpred: Type;
  squash: nat * Fpred -> knot;
  unsquash: knot -> nat * Fpred;
  approxF: nat -> Fpred -> Fpred;
  squash_unsquash : forall k:knot, squash (unsquash k) = k;
  unsquash_squash : forall (n:nat) (f:Fpred),
    unsquash (squash (n,f)) = (n, approxF n f)
}.Class Input: Type := {
  knot: Type;
  Fpred: Type;
  squash: nat * Fpred -> knot;
  unsquash: knot -> nat * Fpred;
  approxF: nat -> Fpred -> Fpred;
  squash_unsquash : forall k:knot, squash (unsquash k) = k;
  unsquash_squash : forall (n:nat) (f:Fpred),
    unsquash (squash (n,f)) = (n, approxF n f)
}.Class Input: Type := {
  knot: Type;
  Fpred: Type;
  squash: nat * Fpred -> knot;
  unsquash: knot -> nat * Fpred;
  approxF: nat -> Fpred -> Fpred;
  squash_unsquash : forall k:knot, squash (unsquash k) = k;
  unsquash_squash : forall (n:nat) (f:Fpred),
    unsquash (squash (n,f)) = (n, approxF n f)
}.Class Input: Type := {
  knot: Type;
  Fpred: Type;
  squash: nat * Fpred -> knot;
  unsquash: knot -> nat * Fpred;
  approxF: nat -> Fpred -> Fpred;
  squash_unsquash : forall k:knot, squash (unsquash k) = k;
  unsquash_squash : forall (n:nat) (f:Fpred),
    unsquash (squash (n,f)) = (n, approxF n f)
}.Class Output (input: Input): Prop := {
  unsquash_inj : forall k1 k2,
    unsquash k1 = unsquash k2 ->
    k1 = k2;
  squash_surj : forall k, exists n, exists Fp,
    squash (n, Fp) = k;
  unsquash_approx : forall k n Fp,
    unsquash k = (n, Fp) ->
    Fp = approxF n Fp
}.Class Output (input: Input): Prop := {
  unsquash_inj : forall k1 k2,
    unsquash k1 = unsquash k2 ->
    k1 = k2;
  squash_surj : forall k, exists n, exists Fp,
    squash (n, Fp) = k;
  unsquash_approx : forall k n Fp,
    unsquash k = (n, Fp) ->
    Fp = approxF n Fp
}.Class Output (input: Input): Prop := {
  unsquash_inj : forall k1 k2,
    unsquash k1 = unsquash k2 ->
    k1 = k2;
  squash_surj : forall k, exists n, exists Fp,
    squash (n, Fp) = k;
  unsquash_approx : forall k n Fp,
    unsquash k = (n, Fp) ->
    Fp = approxF n Fp
}.Class Output (input: Input): Prop := {
  unsquash_inj : forall k1 k2,
    unsquash k1 = unsquash k2 ->
    k1 = k2;
  squash_surj : forall k, exists n, exists Fp,
    squash (n, Fp) = k;
  unsquash_approx : forall k n Fp,
    unsquash k = (n, Fp) ->
    Fp = approxF n Fp
}.

Lemma Proof (kli: Input): Output kli.