Class Input: Type := {
  knot: Type;
  other: Type;
  T: Type;
  t0: T;
  ageable_knot : ageable knot;
  predicate: Type;
  p2p: predicate -> (knot * other -> T);
  approx : nat -> predicate -> predicate;
  pred_ext : forall (p1 p2:predicate),
    (forall x, p2p p1 x = p2p p2 x) ->
    p1 = p2;
  approx_spec : forall n p ko,
    p2p (approx n p) ko =
     if (le_gt_dec n (level (fst ko))) then t0 else p2p p ko
}.Class Input: Type := {
  knot: Type;
  other: Type;
  T: Type;
  t0: T;
  ageable_knot : ageable knot;
  predicate: Type;
  p2p: predicate -> (knot * other -> T);
  approx : nat -> predicate -> predicate;
  pred_ext : forall (p1 p2:predicate),
    (forall x, p2p p1 x = p2p p2 x) ->
    p1 = p2;
  approx_spec : forall n p ko,
    p2p (approx n p) ko =
     if (le_gt_dec n (level (fst ko))) then t0 else p2p p ko
}.Class Input: Type := {
  knot: Type;
  other: Type;
  T: Type;
  t0: T;
  ageable_knot : ageable knot;
  predicate: Type;
  p2p: predicate -> (knot * other -> T);
  approx : nat -> predicate -> predicate;
  pred_ext : forall (p1 p2:predicate),
    (forall x, p2p p1 x = p2p p2 x) ->
    p1 = p2;
  approx_spec : forall n p ko,
    p2p (approx n p) ko =
     if (le_gt_dec n (level (fst ko))) then t0 else p2p p ko
}.Class Input: Type := {
  knot: Type;
  other: Type;
  T: Type;
  t0: T;
  ageable_knot : ageable knot;
  predicate: Type;
  p2p: predicate -> (knot * other -> T);
  approx : nat -> predicate -> predicate;
  pred_ext : forall (p1 p2:predicate),
    (forall x, p2p p1 x = p2p p2 x) ->
    p1 = p2;
  approx_spec : forall n p ko,
    p2p (approx n p) ko =
     if (le_gt_dec n (level (fst ko))) then t0 else p2p p ko
}.Class Input: Type := {
  knot: Type;
  other: Type;
  T: Type;
  t0: T;
  ageable_knot : ageable knot;
  predicate: Type;
  p2p: predicate -> (knot * other -> T);
  approx : nat -> predicate -> predicate;
  pred_ext : forall (p1 p2:predicate),
    (forall x, p2p p1 x = p2p p2 x) ->
    p1 = p2;
  approx_spec : forall n p ko,
    p2p (approx n p) ko =
     if (le_gt_dec n (level (fst ko))) then t0 else p2p p ko
}.Class Input: Type := {
  knot: Type;
  other: Type;
  T: Type;
  t0: T;
  ageable_knot : ageable knot;
  predicate: Type;
  p2p: predicate -> (knot * other -> T);
  approx : nat -> predicate -> predicate;
  pred_ext : forall (p1 p2:predicate),
    (forall x, p2p p1 x = p2p p2 x) ->
    p1 = p2;
  approx_spec : forall n p ko,
    p2p (approx n p) ko =
     if (le_gt_dec n (level (fst ko))) then t0 else p2p p ko
}.Class Input: Type := {
  knot: Type;
  other: Type;
  T: Type;
  t0: T;
  ageable_knot : ageable knot;
  predicate: Type;
  p2p: predicate -> (knot * other -> T);
  approx : nat -> predicate -> predicate;
  pred_ext : forall (p1 p2:predicate),
    (forall x, p2p p1 x = p2p p2 x) ->
    p1 = p2;
  approx_spec : forall n p ko,
    p2p (approx n p) ko =
     if (le_gt_dec n (level (fst ko))) then t0 else p2p p ko
}.Class Input: Type := {
  knot: Type;
  other: Type;
  T: Type;
  t0: T;
  ageable_knot : ageable knot;
  predicate: Type;
  p2p: predicate -> (knot * other -> T);
  approx : nat -> predicate -> predicate;
  pred_ext : forall (p1 p2:predicate),
    (forall x, p2p p1 x = p2p p2 x) ->
    p1 = p2;
  approx_spec : forall n p ko,
    p2p (approx n p) ko =
     if (le_gt_dec n (level (fst ko))) then t0 else p2p p ko
}.Class Input: Type := {
  knot: Type;
  other: Type;
  T: Type;
  t0: T;
  ageable_knot : ageable knot;
  predicate: Type;
  p2p: predicate -> (knot * other -> T);
  approx : nat -> predicate -> predicate;
  pred_ext : forall (p1 p2:predicate),
    (forall x, p2p p1 x = p2p p2 x) ->
    p1 = p2;
  approx_spec : forall n p ko,
    p2p (approx n p) ko =
     if (le_gt_dec n (level (fst ko))) then t0 else p2p p ko
}.Class Input: Type := {
  knot: Type;
  other: Type;
  T: Type;
  t0: T;
  ageable_knot : ageable knot;
  predicate: Type;
  p2p: predicate -> (knot * other -> T);
  approx : nat -> predicate -> predicate;
  pred_ext : forall (p1 p2:predicate),
    (forall x, p2p p1 x = p2p p2 x) ->
    p1 = p2;
  approx_spec : forall n p ko,
    p2p (approx n p) ko =
     if (le_gt_dec n (level (fst ko))) then t0 else p2p p ko
}.Class Input: Type := {
  knot: Type;
  other: Type;
  T: Type;
  t0: T;
  ageable_knot : ageable knot;
  predicate: Type;
  p2p: predicate -> (knot * other -> T);
  approx : nat -> predicate -> predicate;
  pred_ext : forall (p1 p2:predicate),
    (forall x, p2p p1 x = p2p p2 x) ->
    p1 = p2;
  approx_spec : forall n p ko,
    p2p (approx n p) ko =
     if (le_gt_dec n (level (fst ko))) then t0 else p2p p ko
}.Class Output (input: Input): Prop := {
  approx_approx1 : forall m n,
    approx n = approx n oo approx (m+n);
  approx_approx2 : forall m n,
    approx n = approx (m+n) oo approx n
}.Class Output (input: Input): Prop := {
  approx_approx1 : forall m n,
    approx n = approx n oo approx (m+n);
  approx_approx2 : forall m n,
    approx n = approx (m+n) oo approx n
}.Class Output (input: Input): Prop := {
  approx_approx1 : forall m n,
    approx n = approx n oo approx (m+n);
  approx_approx2 : forall m n,
    approx n = approx (m+n) oo approx n
}.

(* Specifications: *)
Lemma Proof (kli: Input): Output kli.
Lemma unsquash_inj : forall k1 k2, unsquash k1 = unsquash k2 -> k1 = k2.
Lemma squash_surj : forall k, exists n, exists Fp, squash (n, Fp) = k.
Lemma unsquash_approx : forall k n Fp, unsquash k = (n, Fp) -> Fp = fmap F (approx n) (approx n) Fp.
Lemma pred_ext : forall (p1 p2:predicate), (forall x, proj1_sig p1 x = proj1_sig p2 x) -> p1 = p2.
Lemma approx_approx1 : forall m n, approx n = approx n oo approx (m+n).
Lemma approx_approx2 : forall m n, approx n = approx (m+n) oo approx n.