# TheoryBodies

body:
  %------------------------------------------------------------------------------
  % Integrable Simple Functions (ISF)
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  % Definition and basic properties of ISF. To be integrable, a simple function
  % must be nonzero only on a set of finite measure.
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  isf[T:TYPE,          (IMPORTING subset_algebra_def[T])
      S:sigma_algebra, (IMPORTING measure_def[T,S])
      m:measure_type]: THEORY

  BEGIN

    IMPORTING measure_space[T,S],
              measure_theory[T,S,m],
              measure_props[T,S,m]

    x: VAR T
    f: VAR [T->real]
    g: VAR measurable_function
    X: VAR (S)
    Y: VAR set[T]

    nonzero_set?(f):set[T] = { x | f(x) /= 0}                             % 4.3.1

    nonzero_measurable: LEMMA measurable_set?(nonzero_set?(g))            % 4.3.2

    nonzero_set_phi: LEMMA nonzero_set?(phi(X)) = X

    isf?(f):bool = simple?(f) AND mu_fin?(nonzero_set?(f))                % 4.3.3

    isf_zero: LEMMA isf?(lambda x:0)

    isf: TYPE+ = (isf?) CONTAINING (lambda x:0)

    isf_is_simple: JUDGEMENT isf SUBTYPE_OF simple

    i,i1,i2: VAR isf
    w:       VAR sequence[isf]
    c:       VAR real
    n:       VAR nat
    pn: VAR posnat
    E:       VAR (mu_fin?)
    h:       VAR simple
    nnx:     VAR nnreal

    isf_add:     JUDGEMENT +(i1,i2)     HAS_TYPE isf
    isf_scal:    JUDGEMENT *(c,i)       HAS_TYPE isf
    isf_opp:     JUDGEMENT -(i)         HAS_TYPE isf
    isf_diff:    JUDGEMENT -(i1,i2)     HAS_TYPE isf
    isf_abs:     JUDGEMENT abs(i)       HAS_TYPE isf
    isf_min:     JUDGEMENT min(i1,i2)   HAS_TYPE isf
    isf_max:     JUDGEMENT max(i1,i2)   HAS_TYPE isf
    isf_minimum: JUDGEMENT minimum(w,n) HAS_TYPE isf
    isf_maximum: JUDGEMENT maximum(w,n) HAS_TYPE isf
    isf_plus:    JUDGEMENT plus(i)      HAS_TYPE isf
    isf_minus:   JUDGEMENT minus(i)     HAS_TYPE isf
    isf_sq:      JUDGEMENT sq(i)        HAS_TYPE isf
    isf_prod:    JUDGEMENT *(i1,i2)     HAS_TYPE isf
    isf_phi:     JUDGEMENT phi(E)       HAS_TYPE isf
    isf_expt:    JUDGEMENT expt(i,pn)   HAS_TYPE isf                      % 4.3.4

    isf_times_simple_is_isf: JUDGEMENT *(i,h) HAS_TYPE isf                % 4.3.5

    P: VAR pred[isf]

    isf_induction: LEMMA (P(lambda x: 0) AND
                          (FORALL c,E,i: P(i) => P(c*phi(E)+i)))
                         => P(i)

    p,p1,p2: VAR finite_partition[T]

    finite_partition_of?(f)(p):bool
      = FORALL (E:(p)): S(E) AND constant_over?(f)(E) AND
                        (empty?(E) OR f(choose(E)) = 0 OR mu_fin?(E))

    isf_def: LEMMA isf?(f) <=> EXISTS (p:(finite_partition_of?(f))): TRUE % 4.3.6

    IMPORTING sigma_set@sigma_countable

    isf_integral(i):real                                                  % 4.3.9
      = sigma[real](image[T,real](i,fullset[T]),
          LAMBDA c: IF c = 0 THEN 0
                    ELSE c*mu(inverse_image[T,real](i,singleton[real](c))) ENDIF)

    isf_integral_phi:      LEMMA isf_integral(phi(E)) = mu(E)
    isf_integral_zero:     LEMMA isf_integral(lambda x: 0) = 0

    isf_integral_def: LEMMA finite_partition_of?(i)(p) =>            % 4.3.7
      isf_integral(i)
        = LET f = LAMBDA Y: IF (NOT p(Y)) OR empty?(Y) OR i(choose[T](Y)) = 0
                            THEN 0 ELSE i(choose[T](Y)) * mu(Y) ENDIF
          IN sigma[set[T]](p,f)

    isf_integral_scal:LEMMA isf_integral(c*i) = c*isf_integral(i)
    isf_integral_opp: LEMMA isf_integral(-i)   = -isf_integral(i)
    isf_integral_add: LEMMA isf_integral(i1+i2)=isf_integral(i1)+isf_integral(i2)
    isf_integral_diff:LEMMA isf_integral(i1-i2)=isf_integral(i1)-isf_integral(i2)
    isf_integral_pos: LEMMA (FORALL x: i(x) >= 0) => isf_integral(i) >= 0
                                                                         % 4.3.10

    isf_integral_le: LEMMA (FORALL x: i1(x) <= i2(x)) =>
                            isf_integral(i1) <= isf_integral(i2)
    isf_integral_abs: LEMMA abs(isf_integral(i)) <= isf_integral(abs(i)) % 4.3.11

    isf_bounded: LEMMA EXISTS nnx: FORALL x: -nnx <= i(x) AND i(x) <= nnx
    isf_integral_bound: LEMMA (FORALL x: abs(i(x)) <= nnx) =>       % 4.3.12
                                isf_integral(abs(i)) <= nnx * mu(nonzero_set?(i))

    isf_ae_0: LEMMA (simple?(f) AND ae_0?(f)) <=>                        % 4.3.13
                    (isf?(f) AND  isf_integral(abs(f)) = 0)

    isf_ae_eq:   LEMMA ae_eq?(i1,i2) => isf_integral(i1) = isf_integral(i2)
    isf_ae_0_le: LEMMA ae_nonneg?(i) => 0 <= isf_integral(i)
    isf_ae_le:   LEMMA ae_le?(i1,i2) => isf_integral(i1) <= isf_integral(i2)
    isf_ae_ge_0: LEMMA ae_nonneg?(i) AND isf_integral(i) = 0 => ae_0?(i)
                                                                         % 4.3.14

    u: VAR increasing_nn_simple

    isf_convergence: LEMMA pointwise_converges_upto?(u,i) =>             % 4.3.15
                           converges_upto?((isf_integral o u),isf_integral(i))

  END isf

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 37, column 40) for  nonzero_set?(f)
      % expected type  measurable_set[T, S]
  isf?_TCC1: OBLIGATION
    FORALL (f: [T -> real]):
      simple?(f) IMPLIES measurable_set?[T, S](nonzero_set?(f));

  % Subtype TCC generated (at line 41, column 34) for  (LAMBDA x: 0)
      % expected type  isf
  isf_TCC1: OBLIGATION isf?((LAMBDA x: 0));

  % Judgement subtype TCC generated (at line 43, column 27) for  x
      % expected type  simple[T, S]
  isf_is_simple: OBLIGATION FORALL (x: isf): simple?[T, S](x);

  % Judgement subtype TCC generated (at line 54, column 25) for  i1 + i2
      % expected type  isf
  isf_add: OBLIGATION FORALL (i1, i2): isf?((+[T])(i1, i2));

  % Judgement subtype TCC generated (at line 55, column 25) for  c * i
      % expected type  isf
  isf_scal: OBLIGATION FORALL (c, i): isf?(*[T](c, i));

  % Judgement subtype TCC generated (at line 56, column 25) for  -i
      % expected type  isf
  isf_opp: OBLIGATION FORALL (i): isf?(-i);

  % Judgement subtype TCC generated (at line 57, column 25) for  i1 - i2
      % expected type  isf
  isf_diff: OBLIGATION FORALL (i1, i2): isf?((-[T])(i1, i2));

  % Judgement subtype TCC generated (at line 58, column 25) for  abs(i)
      % expected type  isf
  isf_abs: OBLIGATION FORALL (i): isf?(abs[T](i));

  % Judgement subtype TCC generated (at line 59, column 25) for  min(i1, i2)
      % expected type  isf
  isf_min: OBLIGATION FORALL (i1, i2): isf?(min[T](i1, i2));

  % Judgement subtype TCC generated (at line 60, column 25) for  max(i1, i2)
      % expected type  isf
  isf_max: OBLIGATION FORALL (i1, i2): isf?(max[T](i1, i2));

  % Judgement subtype TCC generated (at line 61, column 25) for  minimum(w, n)
      % expected type  isf
  isf_minimum: OBLIGATION FORALL (n, w): isf?(minimum[T](w, n));

  % Judgement subtype TCC generated (at line 62, column 25) for  maximum(w, n)
      % expected type  isf
  isf_maximum: OBLIGATION FORALL (n, w): isf?(maximum[T](w, n));

  % Judgement subtype TCC generated (at line 63, column 25) for  plus(i)
      % expected type  isf
  isf_plus: OBLIGATION FORALL (i): isf?(plus[T](i));

  % Judgement subtype TCC generated (at line 64, column 25) for  minus(i)
      % expected type  isf
  isf_minus: OBLIGATION FORALL (i): isf?(minus[T](i));

  % Judgement subtype TCC generated (at line 65, column 25) for  sq(i)
      % expected type  isf
  isf_sq: OBLIGATION FORALL (i): isf?(sq[T](i));

  % Judgement subtype TCC generated (at line 66, column 25) for  i1 * i2
      % expected type  isf
  isf_prod: OBLIGATION FORALL (i1, i2): isf?(*[T](i1, i2));

  % Judgement subtype TCC generated (at line 67, column 25) for  phi(E)
      % expected type  isf
  isf_phi: OBLIGATION FORALL (E): isf?(phi[T, S](E));

  % Judgement subtype TCC generated (at line 68, column 25) for  expt(i, pn)
      % expected type  isf
  isf_expt: OBLIGATION FORALL (i, pn): isf?(expt[T](i, pn));

  % Judgement subtype TCC generated (at line 70, column 37) for  i * h
      % expected type  isf
  isf_times_simple_is_isf: OBLIGATION FORALL (h, i): isf?(*[T](i, h));

  % Subtype TCC generated (at line 82, column 45) for  E
      % expected type  p: (nonempty?[T])
  finite_partition_of?_TCC1: OBLIGATION
    FORALL (f: [T -> real], p: finite_partition[T], E: (p)):
      NOT empty?(E) AND constant_over?(f)(E) AND S(E) IMPLIES nonempty?[T](E);

  % Subtype TCC generated (at line 82, column 64) for  E
      % expected type  measurable_set[T, S]
  finite_partition_of?_TCC2: OBLIGATION
    FORALL (f: [T -> real], p: finite_partition[T], E: (p)):
      NOT f(choose(E)) = 0 AND
       NOT empty?(E) AND constant_over?(f)(E) AND S(E)
       IMPLIES measurable_set?[T, S](E);

  % Subtype TCC generated (at line 89, column 18) for
      % image[T, real](i, fullset[T])
      % expected type  countable_set[real]
  isf_integral_TCC1: OBLIGATION
    FORALL (i: isf): is_countable[real](image[T, real](i, fullset[T]));

  % Subtype TCC generated (at line 91, column 28) for
      % inverse_image[T, real](i, singleton[real](c))
      % expected type  {m1: (S) | mu_fin?(m1)}
  isf_integral_TCC2: OBLIGATION
    FORALL (i: isf, c):
      NOT c = 0 IMPLIES
       S(inverse_image[T, real](i, singleton[real](c))) AND
        mu_fin?[T, S, m](inverse_image[T, real](i, singleton[real](c)));

  % Subtype TCC generated (at line 90, column 8) for
      % LAMBDA c:
      %   IF c = 0 THEN 0
      %   ELSE c * mu(inverse_image[T, real](i, singleton[real](c)))
      %   ENDIF
      % expected type  (convergent?(image[T, real](i, fullset[T])))
  isf_integral_TCC3: OBLIGATION
    FORALL (i: isf):
      convergent?[real]
          (image[T, real](i, fullset[T]))
          (LAMBDA c:
             IF c = 0 THEN 0
             ELSE c *
                   mu[T, S, m](inverse_image[T, real](i, singleton[real](c)))
             ENDIF);

  % Subtype TCC generated (at line 93, column 57) for  E
      % expected type  {m1: (S) | mu_fin?(m1)}
  isf_integral_phi_TCC1: OBLIGATION
    FORALL (E: (mu_fin?)): S(E) AND mu_fin?[T, S, m](E);

  % Subtype TCC generated (at line 98, column 68) for  Y
      % expected type  p: (nonempty?[T])
  isf_integral_def_TCC1: OBLIGATION
    FORALL (i: isf, p: finite_partition[T]):
      finite_partition_of?(i)(p) IMPLIES
       (FORALL (Y): NOT empty?(Y) AND p(Y) IMPLIES nonempty?[T](Y));

  % Subtype TCC generated (at line 99, column 59) for  Y
      % expected type  {m1: (S) | mu_fin?(m1)}
  isf_integral_def_TCC2: OBLIGATION
    FORALL (i: isf, p: finite_partition[T]):
      finite_partition_of?(i)(p) IMPLIES
       (FORALL (Y):
          p(Y) AND NOT empty?(Y) AND NOT i(choose[T](Y)) = 0 IMPLIES
           S(Y) AND mu_fin?[T, S, m](Y));

  % Subtype TCC generated (at line 100, column 25) for  p
      % expected type  countable_set[set[T]]
  isf_integral_def_TCC3: OBLIGATION
    FORALL (i: isf, p: finite_partition[T]):
      finite_partition_of?(i)(p) IMPLIES
       (FORALL (f: [set[T] -> real]):
          (f =
            (LAMBDA Y:
               IF (NOT p(Y)) OR empty?(Y) OR i(choose[T](Y)) = 0 THEN 0
               ELSE i(choose[T](Y)) * mu(Y)
               ENDIF))
           IMPLIES is_countable[set[T]](p));

  % Subtype TCC generated (at line 100, column 27) for  f
      % expected type  (convergent?(p))
  isf_integral_def_TCC4: OBLIGATION
    FORALL (i: isf, p: finite_partition[T]):
      finite_partition_of?(i)(p) IMPLIES
       (FORALL (f: [set[T] -> real]):
          (f =
            (LAMBDA Y:
               IF (NOT p(Y)) OR empty?(Y) OR i(choose[T](Y)) = 0 THEN 0
               ELSE i(choose[T](Y)) * mu(Y)
               ENDIF))
           IMPLIES convergent?[set[T]](p)(f));

  % Subtype TCC generated (at line 115, column 63) for  nonzero_set?(i)
      % expected type  {m1: (S) | mu_fin?(m1)}
  isf_integral_bound_TCC1: OBLIGATION
    FORALL (i: isf, nnx: nnreal):
      (FORALL x: abs(i(x)) <= nnx) IMPLIES
       S(nonzero_set?(i)) AND mu_fin?[T, S, m](nonzero_set?(i));

  % Subtype TCC generated (at line 118, column 45) for  abs(f)
      % expected type  isf
  isf_ae_0_TCC1: OBLIGATION
    FORALL (f: [T -> real]): isf?(f) IMPLIES isf?(abs[T](f));

  % Subtype TCC generated (at line 129, column 57) for  u
      % expected type  [nat -> isf]
  isf_convergence_TCC1: OBLIGATION
    FORALL (i: isf, u: increasing_nn_simple[T, S]):
      pointwise_converges_upto?(u, i) IMPLIES (FORALL (x1: nat): isf?(u(x1)));


body:
  %------------------------------------------------------------------------------
  % Non-negative Integrals
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  % Definition and basic properties of integrals of functions f:[T->nnreal]
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  nn_integral[T:TYPE,          (IMPORTING subset_algebra_def[T])
              S:sigma_algebra, (IMPORTING measure_def[T,S])
              m:measure_type]: THEORY

  BEGIN

    IMPORTING measure_space[T,S],
              measure_props[T,S,m],
              measure_theory[T,S,m],
              isf[T,S,m]

    convergent?: MACRO pred[sequence[real]] = topological_convergence.convergent?
    limit:       MACRO [convergent->real]   = topological_convergence.limit

    n: VAR nat
    pn: VAR posnat
    x: VAR T
    c: VAR nnreal
    E: VAR measurable_set
    F: VAR (mu_fin?)
    g: VAR measurable_function
    h: VAR nn_bounded_measurable

    nn_isf?(i:isf):bool = FORALL x: i(x) >= 0

    nn_isf: TYPE+ = (nn_isf?) CONTAINING (lambda x: 0)

    i: VAR nn_isf
    w: VAR sequence[nn_isf]

    increasing_nn_isf?(u:sequence[nn_isf]):bool = pointwise_increasing?(u)

    increasing_nn_isf: TYPE+ = (increasing_nn_isf?) CONTAINING 
                                                 (lambda n: lambda x: 0)

    u,u1,u2: VAR increasing_nn_isf

    nn_integrable?(g:[T->nnreal]):bool                                    % 4.4.1
      = EXISTS u: pointwise_convergence?(u,g) AND convergent?(isf_integral o u)

    nn_integrable_zero:      LEMMA nn_integrable?(lambda x: 0)

    nn_integrable: TYPE+ = (nn_integrable?) CONTAINING (lambda x: 0)

    f,f1,f2: VAR nn_integrable

    nn_integrable_is_nonneg: LEMMA f(x) >= 0

    nn_integrable_is_measurable:
                   JUDGEMENT nn_integrable SUBTYPE_OF measurable_function % 4.4.1

    nn_convergence: LEMMA pointwise_convergence?(u1,f) AND                % 4.4.2
                          pointwise_convergence?(u2,f) AND
                          convergent?(isf_integral o u1) =>
                          (convergent?(isf_integral o u2) AND
                          limit(isf_integral o u1) = limit(isf_integral o u2))

    nn_integral(f):nnreal                                                 % 4.4.3
      = limit(isf_integral o choose({u | pointwise_convergence?(u,f)}))

    nn_integrable_add:       JUDGEMENT +(f1,f2) HAS_TYPE   nn_integrable
    nn_integrable_scal:      JUDGEMENT *(c,f)   HAS_TYPE   nn_integrable
    nn_isf_is_nn_integrable: JUDGEMENT nn_isf   SUBTYPE_OF nn_integrable  % 4.4.4

    nn_integral_isf:  LEMMA nn_integral(i) = isf_integral(i)              % 4.4.4

    nn_integrable_le: LEMMA (FORALL x: 0 <= g(x) AND g(x) <= f(x)) =>     % 4.4.5
                            (nn_integrable?(g) AND
                             nn_integral(g) <= nn_integral(f))

    nn_integral_zero:LEMMA nn_integral(lambda x: 0) = 0
    nn_integral_phi: LEMMA nn_integral(phi(F)) = mu(F)
    nn_integral_add: LEMMA nn_integral(f1+f2) = nn_integral(f1) + nn_integral(f2)
    nn_integral_scal:LEMMA nn_integral(c*f)   = c * nn_integral(f)

    nn_integrable_prod:    JUDGEMENT *(f,h)       HAS_TYPE nn_integrable

    nn_indefinite_integrable: LEMMA nn_integrable?(phi(E)*f)              % 4.4.6

    nn_0_le:    LEMMA 0 <= nn_integral(f)

    nn_integral_def: LEMMA
       EXISTS u: pointwise_convergence?(u,f) AND
                 convergence?(isf_integral o u, nn_integral(f))

  END nn_integral

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 39, column 40) for  (LAMBDA x: 0)
      % expected type  nn_isf
  nn_isf_TCC1: OBLIGATION
    isf?[T, S, m]((LAMBDA x: 0)) AND nn_isf?((LAMBDA x: 0));

  % Subtype TCC generated (at line 47, column 48) for  (LAMBDA n: LAMBDA x: 0)
      % expected type  increasing_nn_isf
  increasing_nn_isf_TCC1: OBLIGATION
    increasing_nn_isf?((LAMBDA n: LAMBDA x: 0));

  % Subtype TCC generated (at line 56, column 54) for  (LAMBDA x: 0)
      % expected type  nn_integrable
  nn_integrable_TCC1: OBLIGATION nn_integrable?((LAMBDA x: 0));

  % Judgement subtype TCC generated (at line 63, column 27) for  x
      % expected type  measurable_function[T, S]
  nn_integrable_is_measurable: OBLIGATION
    FORALL (x: nn_integrable): measurable_function?[T, S](x);

  % Subtype TCC generated (at line 72, column 34) for
      % {u | pointwise_convergence?(u, f)}
      % expected type  p: (nonempty?[increasing_nn_isf])
  nn_integral_TCC1: OBLIGATION
    FORALL (f: nn_integrable):
      nonempty?[increasing_nn_isf]({u | pointwise_convergence?[T](u, f)});

  % Subtype TCC generated (at line 72, column 12) for
      % isf_integral o choose({u | pointwise_convergence?(u, f)})
      % expected type  convergent[real, (metric_induced_topology)]
  nn_integral_TCC2: OBLIGATION
    FORALL (f: nn_integrable):
      convergent?
          [real,
           (metric_induced_topology[real, (LAMBDA (x, y: real): abs(x - y))])]
          (o[nat, isf[T, S, m], real]
               (isf_integral[T, S, m],
                choose[increasing_nn_isf]
                    ({u | pointwise_convergence?[T](u, f)})));

  % Subtype TCC generated (at line 72, column 6) for
      % limit(isf_integral o choose({u | pointwise_convergence?(u, f)}))
      % expected type  nnreal
  nn_integral_TCC3: OBLIGATION
    FORALL (f: nn_integrable):
      limit(o[nat, isf[T, S, m], real]
                (isf_integral[T, S, m],
                 choose[increasing_nn_isf]
                     ({u | pointwise_convergence?[T](u, f)})))
       >= 0;

  % Judgement subtype TCC generated (at line 74, column 37) for  f1 + f2
      % expected type  nn_integrable
  nn_integrable_add: OBLIGATION
    FORALL (f1, f2):
      (FORALL (x1: T): ((+[T])(f1, f2))(x1) >= 0) AND
       nn_integrable?((+[T])(f1, f2));

  % Judgement subtype TCC generated (at line 75, column 37) for  c * f
      % expected type  nn_integrable
  nn_integrable_scal: OBLIGATION
    FORALL (c, f):
      (FORALL (x1: T): (*[T](c, f))(x1) >= 0) AND nn_integrable?(*[T](c, f));

  % Judgement subtype TCC generated (at line 76, column 37) for  x
      % expected type  nn_integrable
  nn_isf_is_nn_integrable: OBLIGATION
    FORALL (x: nn_isf): (FORALL (x1: T): x(x1) >= 0) AND nn_integrable?(x);

  % Subtype TCC generated (at line 81, column 42) for  g
      % expected type  [T -> nnreal]
  nn_integrable_le_TCC1: OBLIGATION
    FORALL (f: nn_integrable, g: measurable_function[T, S]):
      (FORALL x: 0 <= g(x) AND g(x) <= f(x)) IMPLIES
       (FORALL (x1: T): g(x1) >= 0);

  % Subtype TCC generated (at line 85, column 37) for  phi(F)
      % expected type  nn_integrable
  nn_integral_phi_TCC1: OBLIGATION
    FORALL (F: (mu_fin?)): nn_integrable?(phi[T, S](F));

  % Subtype TCC generated (at line 85, column 50) for  F
      % expected type  {m1: (S) | mu_fin?(m1)}
  nn_integral_phi_TCC2: OBLIGATION
    FORALL (F: (mu_fin?)): S(F) AND mu_fin?[T, S, m](F);

  % Judgement subtype TCC generated (at line 89, column 35) for  f * h
      % expected type  nn_integrable
  nn_integrable_prod: OBLIGATION
    FORALL (f, h):
      (FORALL (x1: T): (*[T](f, h))(x1) >= 0) AND nn_integrable?(*[T](f, h));

  % Subtype TCC generated (at line 91, column 49) for  phi(E) * f
      % expected type  [T -> nnreal]
  nn_indefinite_integrable_TCC1: OBLIGATION
    FORALL (E: measurable_set[T, S], f: nn_integrable, x1: T):
      (*[T](phi[T, S](E), f))(x1) >= 0;


body:
  %------------------------------------------------------------------------------
  % Integrals
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  % Definition and basic properties of integrals for functions f: [T->real]
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  integral[T:TYPE,          (IMPORTING subset_algebra_def[T])
           S:sigma_algebra, (IMPORTING measure_def[T,S])
           m:measure_type]: THEORY

  BEGIN

    IMPORTING measure_space[T,S],
              measure_theory[T,S,m],
              nn_integral[T,S,m]

    g,g1,g2,g3,g4: VAR nn_integrable
    x:             VAR T

    integrable?(f:[T->real]):bool = EXISTS (g,h:nn_integrable): f = g-h  % 4.4.7

    integrable: TYPE+ = (integrable?) CONTAINING (lambda x: 0)

    nn_integrable_is_integrable:
                 JUDGEMENT nn_integrable SUBTYPE_OF integrable           % 4.4.10
    isf_is_integrable:
                 JUDGEMENT isf           SUBTYPE_OF integrable           % 4.4.15
    integrable_is_measurable:
                 JUDGEMENT integrable    SUBTYPE_OF measurable_function

    f,f1,f2: VAR integrable
    w:       VAR sequence[integrable]
    f0:      VAR [T->real]
    h:       VAR measurable_function
    epsilon: VAR posreal
    c:       VAR real
    nnc:     VAR nnreal
    E:       VAR measurable_set
    F:       VAR (mu_fin?)
    i:       VAR isf
    n:       VAR nat

    integrable_equiv: LEMMA g1 - g3 = g2 - g4 =>                    % 4.4.8
                            nn_integral(g1) - nn_integral(g3) =
                                   nn_integral(g2) - nn_integral(g4)

    integrable_add:  JUDGEMENT +(f1,f2)    HAS_TYPE integrable
    integrable_scal: JUDGEMENT *(c,f)      HAS_TYPE integrable
    integrable_opp:  JUDGEMENT -(f)        HAS_TYPE integrable
    integrable_diff: JUDGEMENT -(f1,f2)    HAS_TYPE integrable

    integrable_zero: LEMMA integrable?(lambda x: 0)

    integrals(f):set[real]
      = {c| EXISTS (g,h:nn_integrable): f = g-h AND
                                        c = nn_integral(g) - nn_integral(h)}

    nonempty_integrals:  LEMMA nonempty?[real](integrals(f))
    singleton_integrals: LEMMA singleton?[real](integrals(f))

    integral(f):real = choose[real](integrals(f))                        % 4.4.9

    nn_integrable_is_nn_integrable:
                            LEMMA (FORALL x: f(x) >= 0) => nn_integrable?(f)
    integral_nn:            LEMMA integral(g) = nn_integral(g)           % 4.4.10

    integral_zero:   LEMMA integral(lambda x: 0) = 0                     % 4.4.11
    integral_phi:    LEMMA integral(phi(F)) = mu(F)
    integral_add:    LEMMA integral(f1+f2)  = integral(f1) + integral(f2)
    integral_scal:   LEMMA integral(c*f)    = c*integral(f)
    integral_opp:    LEMMA integral(-f)     = -integral(f)
    integral_diff:   LEMMA integral(f1-f2 ) = integral(f1) - integral(f2)
    integral_nonneg: LEMMA (FORALL x: f(x) >= 0) => integral(f) >= 0

    integrable_abs:   JUDGEMENT abs(f)      HAS_TYPE integrable          % 4.4.12
    integrable_max:   JUDGEMENT max(f1,f2)  HAS_TYPE integrable          % 4.4.13
    integrable_min:   JUDGEMENT min(f1,f2)  HAS_TYPE integrable          % 4.4.13
    integrable_plus:  JUDGEMENT plus(f)     HAS_TYPE integrable          % 4.4.12
    integrable_minus: JUDGEMENT minus(f)    HAS_TYPE integrable          % 4.4.12

    integral_abs:       LEMMA abs(integral(f)) <= integral(abs(f))       % 4.4.12
    integrable_pm_def:  LEMMA integrable?(f0) <=>                        % 4.4.12
                              (integrable?(plus(f0)) AND integrable?(minus(f0)))
    integral_pm:        LEMMA integral(f) = integral(plus(f))-integral(minus(f))
    integrable_abs_def: LEMMA integrable?(abs(h)) <=> integrable?(h)     % 4.4.12

    integrable_nz_finite: LEMMA                                          % 4.4.14
                          measurable_set?({x | abs(f(x)) >= epsilon}) AND
                          mu_fin?({x | abs(f(x)) >= epsilon})

    isf_integral:   LEMMA integral(i) = isf_integral(i)                  % 4.4.15

    integral_ae_eq: LEMMA ae_eq?(f,h) =>                                 % 4.4.16
                          (integrable?(h) AND integral(f) = integral(h))

    integral_prod:  LEMMA ae_le?(abs(h),lambda x: nnc) =>                % 4.4.17
                          (integrable?(f*h) AND
                           integral(abs(f*h)) <= nnc * integral(abs(f)))

    indefinite_integrable:  LEMMA integrable?(phi(E)*f)                  % 4.4.18

    integral_ae_le:  LEMMA ae_le?(f1,f2) =>                              % 4.4.19
                           integral(f1) <= integral(f2)

    integral_ae_abs: LEMMA ae_le?(abs(h),abs(f)) =>                      % 4.4.20
                           (integrable?(h) AND
                            abs(integral(h)) <= integral(abs(f)))

    bounded_is_indefinite_integrable: LEMMA
        bounded?(phi(F)*h) =>
          (integrable?(phi(F)*h) AND
           abs(integral(phi(F)*h)) <= mu(F)*sup_norm(phi(F)*h))

    integral_abs_0:   LEMMA integral(abs(f)) = 0 => ae_0?(f)             % 4.4.21
    measurable_ae_0:  LEMMA ae_0?(h) =>
                            (integrable?(h) AND integral(h) = 0)
    integral_ae_ge_0: LEMMA ae_nonneg?(f) AND integral(f) = 0 => ae_0?(f)

    integrable_maximum:   JUDGEMENT maximum(w,n)  HAS_TYPE integrable
    integrable_minimum:   JUDGEMENT minimum(w,n)  HAS_TYPE integrable

    integrable_split: LEMMA FORALL (h:[T->real]):
      integrable?(h) <=>
             integrable?(phi(E)*h) AND integrable?(phi(complement(E))*h)

    integral_split: LEMMA
      integral(f) = integral(phi(E)*f) + integral(phi(complement(E))*f)

  END integral

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 29, column 48) for  (LAMBDA x: 0)
      % expected type  integrable
  integrable_TCC1: OBLIGATION integrable?((LAMBDA x: 0));

  % Judgement subtype TCC generated (at line 32, column 25) for  x
      % expected type  integrable
  nn_integrable_is_integrable: OBLIGATION
    FORALL (x: nn_integrable): integrable?(x);

  % Judgement subtype TCC generated (at line 34, column 25) for  x
      % expected type  integrable
  isf_is_integrable: OBLIGATION FORALL (x: isf): integrable?(x);

  % Judgement subtype TCC generated (at line 36, column 25) for  x
      % expected type  measurable_function[T, S]
  integrable_is_measurable: OBLIGATION
    FORALL (x: integrable): measurable_function?[T, S](x);

  % Judgement subtype TCC generated (at line 54, column 29) for  f1 + f2
      % expected type  integrable
  integrable_add: OBLIGATION FORALL (f1, f2): integrable?((+[T])(f1, f2));

  % Judgement subtype TCC generated (at line 55, column 29) for  c * f
      % expected type  integrable
  integrable_scal: OBLIGATION FORALL (c, f): integrable?(*[T](c, f));

  % Judgement subtype TCC generated (at line 56, column 29) for  -f
      % expected type  integrable
  integrable_opp: OBLIGATION FORALL (f): integrable?(-f);

  % Judgement subtype TCC generated (at line 57, column 29) for  f1 - f2
      % expected type  integrable
  integrable_diff: OBLIGATION FORALL (f1, f2): integrable?((-[T])(f1, f2));

  % Subtype TCC generated (at line 68, column 34) for  integrals(f)
      % expected type  p: (nonempty?)
  integral_TCC1: OBLIGATION
    FORALL (f: integrable): nonempty?[real](integrals(f));

  % Subtype TCC generated (at line 75, column 47) for  F
      % expected type  {m1: (S) | mu_fin?(m1)}
  integral_phi_TCC1: OBLIGATION
    FORALL (F: (mu_fin?)): S(F) AND mu_fin?[T, S, m](F);

  % Judgement subtype TCC generated (at line 82, column 30) for  abs(f)
      % expected type  integrable
  integrable_abs: OBLIGATION FORALL (f): integrable?(abs[T](f));

  % Judgement subtype TCC generated (at line 83, column 30) for  max(f1, f2)
      % expected type  integrable
  integrable_max: OBLIGATION FORALL (f1, f2): integrable?(max[T](f1, f2));

  % Judgement subtype TCC generated (at line 84, column 30) for  min(f1, f2)
      % expected type  integrable
  integrable_min: OBLIGATION FORALL (f1, f2): integrable?(min[T](f1, f2));

  % Judgement subtype TCC generated (at line 85, column 30) for  plus(f)
      % expected type  integrable
  integrable_plus: OBLIGATION FORALL (f): integrable?(plus[T](f));

  % Judgement subtype TCC generated (at line 86, column 30) for  minus(f)
      % expected type  integrable
  integrable_minus: OBLIGATION FORALL (f): integrable?(minus[T](f));

  % Subtype TCC generated (at line 105, column 34) for  abs(f * h)
      % expected type  integrable
  integral_prod_TCC1: OBLIGATION
    FORALL (f: integrable, h: measurable_function[T, S], nnc: nnreal):
      ae_le?(abs(h), LAMBDA x: nnc) AND integrable?(f * h) IMPLIES
       integrable?(abs[T](*[T](f, h)));

  % Judgement subtype TCC generated (at line 126, column 34) for  maximum(w, n)
      % expected type  integrable
  integrable_maximum: OBLIGATION FORALL (n, w): integrable?(maximum[T](w, n));

  % Judgement subtype TCC generated (at line 127, column 34) for  minimum(w, n)
      % expected type  integrable
  integrable_minimum: OBLIGATION FORALL (n, w): integrable?(minimum[T](w, n));

  % Subtype TCC generated (at line 134, column 27) for  phi(E) * f
      % expected type  integrable
  integral_split_TCC1: OBLIGATION
    FORALL (E: measurable_set[T, S], f: integrable):
      integrable?(*[T](phi[T, S](E), f));

  % Subtype TCC generated (at line 134, column 48) for  phi(complement(E)) * f
      % expected type  integrable
  integral_split_TCC2: OBLIGATION
    FORALL (E: measurable_set[T, S], f: integrable):
      integrable?(*[T](phi[T, S](complement[T](E)), f));


body:
  %------------------------------------------------------------------------------
  % A primitive version of the Monotone Convergence Theorem
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  integral_convergence_scaf[T:TYPE,        (IMPORTING subset_algebra_def[T])
                            S:sigma_algebra,(IMPORTING measure_def[T,S])
                            m:measure_type]: THEORY

  BEGIN

    IMPORTING measure_space[T,S],
              measure_theory[T,S,m],
              integral[T,S,m]

    f: VAR [T->real]
    F: VAR sequence[integrable]

    monotone_convergence_scaf: LEMMA                                      % 4.5.1
       pointwise_converges_upto?(F,f) AND bounded?(integral o F) =>
       (integrable?(f) AND converges_upto?((integral o F), integral(f)))

  END integral_convergence_scaf


body:
  %------------------------------------------------------------------------------
  % Monotone and Dominated Convergence Theorems
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  integral_convergence[T:TYPE,         (IMPORTING subset_algebra_def[T])
                       S:sigma_algebra,(IMPORTING measure_def[T,S])
                       m:measure_type]: THEORY

  BEGIN

    IMPORTING integral_convergence_scaf[T,S,m]

    i,j,n: VAR nat
    f,g: VAR integrable
    F: VAR sequence[integrable]
    E: VAR negligible
    x: VAR T

    monotone_convergence: THEOREM                                         % 4.5.3
        ae_increasing?(F) =>
        (((EXISTS f: ae_convergence?(F,f)) <=> bounded?(integral o F)) AND
         FORALL f: ae_convergence?(F,f) =>
                   converges_upto?((integral o F), integral(f)))

    dominated_convergence: THEOREM                                        % 4.5.4
      (FORALL n: ae_le?(abs(F(n)),f)) AND ae_convergent?(F) =>
       EXISTS g: ae_convergence?(F,g) AND convergence?(integral o F, integral(g))

  END integral_convergence


body:
  %------------------------------------------------------------------------------
  % Measure Equality
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  % If mu(E) = nu(E) for every measurable set E, then the integrals are the same.
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  measure_equality[T:TYPE,        (IMPORTING subset_algebra_def[T])
                   S:sigma_algebra]: THEORY

  BEGIN

    IMPORTING measure_def[T,S]

    mu,nu: VAR measure_type
    x:     VAR T
    f:     VAR [T->real]
    g:     VAR [T->nnreal]
    E:     VAR (S)

    IMPORTING integral

    measure_eq_isf?: LEMMA (FORALL E: x_eq(mu(E),nu(E))) =>
                              (isf?[T,S,mu](f) <=> isf?[T,S,nu](f))

    measure_eq_isf:  LEMMA (FORALL E: x_eq(mu(E),nu(E))) AND
                              (isf?[T,S,mu](f) OR isf?[T,S,nu](f)) =>
                              (isf_integral[T,S,mu](f) = isf_integral[T,S,nu](f))

    measure_eq_nn_integrable?: LEMMA
      (FORALL E: x_eq(mu(E),nu(E))) =>
      (nn_integrable?[T,S,mu](g) <=> nn_integrable?[T,S,nu](g))

    measure_eq_nn_integral:  LEMMA
      (FORALL E: x_eq(mu(E),nu(E))) AND
      (nn_integrable?[T,S,mu](g) OR nn_integrable?[T,S,nu](g)) =>
      (nn_integral[T,S,mu](g) = nn_integral[T,S,nu](g))

    measure_eq_integrable?: LEMMA
      (FORALL E: x_eq(mu(E),nu(E))) =>
      (integrable?[T,S,mu](f) <=> integrable?[T,S,nu](f))

    measure_eq_integral:  LEMMA
      (FORALL E: x_eq(mu(E),nu(E))) AND
      (integrable?[T,S,mu](f) OR integrable?[T,S,nu](f)) =>
      (integral[T,S,mu](f) = integral[T,S,nu](f))

  END measure_equality

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 34, column 50) for  f
      % expected type  isf[T, S, mu]
  measure_eq_isf_TCC1: OBLIGATION
    FORALL (f: [T -> real], mu, nu: measure_type[T, S]):
      ((isf?[T, S, mu](f) OR isf?[T, S, nu](f)) AND
        (FORALL E: x_eq(mu(E), nu(E))))
       IMPLIES isf?[T, S, mu](f);

  % Subtype TCC generated (at line 34, column 76) for  f
      % expected type  isf[T, S, nu]
  measure_eq_isf_TCC2: OBLIGATION
    FORALL (f: [T -> real], mu, nu: measure_type[T, S]):
      ((isf?[T, S, mu](f) OR isf?[T, S, nu](f)) AND
        (FORALL E: x_eq(mu(E), nu(E))))
       IMPLIES isf?[T, S, nu](f);

  % Subtype TCC generated (at line 43, column 25) for  g
      % expected type  nn_integrable[T, S, mu]
  measure_eq_nn_integral_TCC1: OBLIGATION
    FORALL (g: [T -> nnreal], mu, nu: measure_type[T, S]):
      ((nn_integrable?[T, S, mu](g) OR nn_integrable?[T, S, nu](g)) AND
        (FORALL E: x_eq(mu(E), nu(E))))
       IMPLIES nn_integrable?[T, S, mu](g);

  % Subtype TCC generated (at line 43, column 50) for  g
      % expected type  nn_integrable[T, S, nu]
  measure_eq_nn_integral_TCC2: OBLIGATION
    FORALL (g: [T -> nnreal], mu, nu: measure_type[T, S]):
      ((nn_integrable?[T, S, mu](g) OR nn_integrable?[T, S, nu](g)) AND
        (FORALL E: x_eq(mu(E), nu(E))))
       IMPLIES nn_integrable?[T, S, nu](g);

  % Subtype TCC generated (at line 52, column 22) for  f
      % expected type  integrable[T, S, mu]
  measure_eq_integral_TCC1: OBLIGATION
    FORALL (f: [T -> real], mu, nu: measure_type[T, S]):
      ((integrable?[T, S, mu](f) OR integrable?[T, S, nu](f)) AND
        (FORALL E: x_eq(mu(E), nu(E))))
       IMPLIES integrable?[T, S, mu](f);

  % Subtype TCC generated (at line 52, column 44) for  f
      % expected type  integrable[T, S, nu]
  measure_eq_integral_TCC2: OBLIGATION
    FORALL (f: [T -> real], mu, nu: measure_type[T, S]):
      ((integrable?[T, S, mu](f) OR integrable?[T, S, nu](f)) AND
        (FORALL E: x_eq(mu(E), nu(E))))
       IMPLIES integrable?[T, S, nu](f);


body:
  %------------------------------------------------------------------------------
  % Indefinite Integrals
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  % Properties of \int_E f i.e. integrals of f over measurable subsets E
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  indefinite_integral[T:TYPE,         (IMPORTING subset_algebra_def[T])
                      S:sigma_algebra,(IMPORTING measure_def[T,S])
                      m:measure_type]: THEORY

  BEGIN

    IMPORTING measure_props[T,S,m],
              integral[T,S,m],
              integral_convergence[T,S,m]

    f,f1,f2: VAR integrable
    g:       VAR [T->real]
    h:       VAR measurable_function[T,S]
    DX:      VAR disjoint_indexed_measurable
    E,E1,E2: VAR measurable_set
    F:       VAR (mu_fin?)
    N:       VAR null_set
    c:       VAR real
    x:       VAR T
    n:       VAR nat

    integrable?(E)(g):bool = integrable?(phi(E)*g)

    integral(E:measurable_set,f:(integrable?(E))):real = integral(phi(E)*f)
                                                                         % 4.4.22

    indefinite_emptyset: LEMMA integral(emptyset,g) = 0
    indefinite_fullset:  LEMMA integral(fullset,f)  = integral(f)

    indefinite_eq_0: LEMMA FORALL (E:measurable_set,f:(integrable?(E))): % 4.4.23
                           ae_in?(LAMBDA x: f(x) > 0)(E) AND
                           integral(phi(E)*f) = 0 =>
                           (mu_fin?(E) AND mu(E) = 0)

    indefinite_eq:   LEMMA (FORALL E: integral(E,f1) = integral(E,f2)) =>
                           ae_eq?(f1,f2)                                 % 4.4.24

    indefinite_phi:  LEMMA integral(E,phi(F)) = mu(intersection(E,F))
                                                                         % 4.7.2
    indefinite_add:  LEMMA FORALL (E:measurable_set,f1,f2:(integrable?(E))):
                           integral(E,f1+f2) = integral(E,f1) + integral(E,f2)
    indefinite_scal: LEMMA FORALL (E:measurable_set,f:(integrable?(E))):
                           integral(E,(c*f)) = c*integral(E,f)
    indefinite_opp:  LEMMA FORALL (E:measurable_set,f:(integrable?(E))):
                           integral(E,-f)    = -integral(E,f)
    indefinite_diff: LEMMA FORALL (E:measurable_set,f1,f2:(integrable?(E))):
                           integral(E,f1-f2) = integral(E,f1) - integral(E,f2)

    indefinite_ae_eq:LEMMA
                   ae_eq?(f1,f2) <=>
                   (FORALL E: integral(E,f1)=integral(E,f2))
    indefinite_0_le: LEMMA
                   ae_nonneg?(f) <=> (FORALL E: 0 <= integral(E,f))
    indefinite_le:   LEMMA
                   ae_le?(f1,f2) <=> (FORALL E: integral(E,f1) <= integral(E,f2))
    indefinite_pm:   LEMMA FORALL (E:measurable_set,f:(integrable?(E))):
                   integral(E,f) = integral(E,plus(f)) - integral(E,minus(f))

    indefinite_union: LEMMA FORALL (E1,E2:measurable_set,
                                    f:(integrable?(union(E1,E2)))):
      disjoint?(E1,E2) =>
      integral(union(E1,E2),f) = integral(E1,f) + integral(E2,f)

    indefinite_subset: LEMMA FORALL (E1,E2:measurable_set,f:(integrable?(E2))):
                             subset?(E1,E2) AND ae_nonneg?(f) =>
                             integral(E1,f) <= integral(E2,f)

    indefinite_null: LEMMA integral(N,h) = 0

    indefinite_countably_additive: LEMMA                                  % 4.7.3
      convergence?(series(lambda n: integral(DX(n),f)), integral(IUnion(DX),f))

  END indefinite_integral

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 37, column 64) for  phi(E) * f
      % expected type  integrable[T, S, m]
  integral_TCC1: OBLIGATION
    FORALL (E: measurable_set[T, S], f: (integrable?(E))):
      integrable?[T, S, m](*[T](phi[T, S](E), f));

  % Subtype TCC generated (at line 40, column 47) for  g
      % expected type  (integrable?(emptyset))
  indefinite_emptyset_TCC1: OBLIGATION
    FORALL (g: [T -> real]): integrable?(emptyset[T])(g);

  % Subtype TCC generated (at line 41, column 46) for  f
      % expected type  (integrable?(fullset))
  indefinite_fullset_TCC1: OBLIGATION
    FORALL (f: integrable[T, S, m]): integrable?(fullset[T])(f);

  % Subtype TCC generated (at line 46, column 44) for  E
      % expected type  {m1: (S) | mu_fin?(m1)}
  indefinite_eq_0_TCC1: OBLIGATION
    FORALL (E: measurable_set[T, S], f: (integrable?(E))):
      mu_fin?(E) AND
       ae_in?(LAMBDA x: f(x) > 0)(E) AND integral(phi(E) * f) = 0
       IMPLIES S(E);

  % Subtype TCC generated (at line 48, column 47) for  f1
      % expected type  (integrable?(E))
  indefinite_eq_TCC1: OBLIGATION
    FORALL (f1: integrable[T, S, m], E): integrable?(E)(f1);

  % Subtype TCC generated (at line 51, column 36) for  phi(F)
      % expected type  (integrable?(E))
  indefinite_phi_TCC1: OBLIGATION
    FORALL (E: measurable_set[T, S], F: (mu_fin?)):
      integrable?(E)(phi[T, S](F));

  % Subtype TCC generated (at line 51, column 49) for  intersection(E, F)
      % expected type  {m1: (S) | mu_fin?(m1)}
  indefinite_phi_TCC2: OBLIGATION
    FORALL (E: measurable_set[T, S], F: (mu_fin?)):
      S(intersection[T](E, F)) AND mu_fin?[T, S, m](intersection[T](E, F));

  % Subtype TCC generated (at line 54, column 36) for  f1 + f2
      % expected type  (integrable?(E))
  indefinite_add_TCC1: OBLIGATION
    FORALL (E: measurable_set[T, S], f1, f2: (integrable?(E))):
      integrable?(E)((+[T])(f1, f2));

  % Subtype TCC generated (at line 56, column 37) for  (c * f)
      % expected type  (integrable?(E))
  indefinite_scal_TCC1: OBLIGATION
    FORALL (c: real, E: measurable_set[T, S], f: (integrable?(E))):
      integrable?(E)((*[T](c, f)));

  % Subtype TCC generated (at line 58, column 36) for  -f
      % expected type  (integrable?(E))
  indefinite_opp_TCC1: OBLIGATION
    FORALL (E: measurable_set[T, S], f: (integrable?(E))): integrable?(E)(-f);

  % Subtype TCC generated (at line 60, column 36) for  f1 - f2
      % expected type  (integrable?(E))
  indefinite_diff_TCC1: OBLIGATION
    FORALL (E: measurable_set[T, S], f1, f2: (integrable?(E))):
      integrable?(E)((-[T])(f1, f2));

  % Subtype TCC generated (at line 70, column 44) for  plus(f)
      % expected type  (integrable?(E))
  indefinite_pm_TCC1: OBLIGATION
    FORALL (E: measurable_set[T, S], f: (integrable?(E))):
      integrable?(E)(plus[T](f));

  % Subtype TCC generated (at line 70, column 66) for  minus(f)
      % expected type  (integrable?(E))
  indefinite_pm_TCC2: OBLIGATION
    FORALL (E: measurable_set[T, S], f: (integrable?(E))):
      integrable?(E)(minus[T](f));

  % Subtype TCC generated (at line 75, column 43) for  f
      % expected type  (integrable?(E1))
  indefinite_union_TCC1: OBLIGATION
    FORALL (E1, E2: measurable_set[T, S],
            f: (integrable?(union[T](E1, E2)))):
      disjoint?(E1, E2) IMPLIES integrable?(E1)(f);

  % Subtype TCC generated (at line 75, column 60) for  f
      % expected type  (integrable?(E2))
  indefinite_union_TCC2: OBLIGATION
    FORALL (E1, E2: measurable_set[T, S],
            f: (integrable?(union[T](E1, E2)))):
      disjoint?(E1, E2) IMPLIES integrable?(E2)(f);

  % Subtype TCC generated (at line 79, column 39) for  f
      % expected type  (integrable?(E1))
  indefinite_subset_TCC1: OBLIGATION
    FORALL (E1, E2: measurable_set[T, S], f: (integrable?(E2))):
      subset?(E1, E2) AND ae_nonneg?(f) IMPLIES integrable?(E1)(f);

  % Subtype TCC generated (at line 81, column 36) for  h
      % expected type  (integrable?(N))
  indefinite_null_TCC1: OBLIGATION
    FORALL (N: null_set[T, S, m], h: measurable_function[T, S]):
      integrable?(N)(h);

  % Subtype TCC generated (at line 84, column 43) for  DX(n)
      % expected type  measurable_set[T, S]
  indefinite_countably_additive_TCC1: OBLIGATION
    FORALL (DX: disjoint_indexed_measurable[T, S], n):
      measurable_set?[T, S](DX(n));

  % Subtype TCC generated (at line 84, column 49) for  f
      % expected type  (integrable?(DX(n)))
  indefinite_countably_additive_TCC2: OBLIGATION
    FORALL (DX: disjoint_indexed_measurable[T, S], f: integrable[T, S, m],
            n):
      integrable?(DX(n))(f);

  % Subtype TCC generated (at line 84, column 63) for  IUnion(DX)
      % expected type  measurable_set[T, S]
  indefinite_countably_additive_TCC3: OBLIGATION
    FORALL (DX: disjoint_indexed_measurable[T, S]):
      measurable_set?[T, S](IUnion[nat, T](DX));

  % Subtype TCC generated (at line 84, column 74) for  f
      % expected type  (integrable?(IUnion(DX)))
  indefinite_countably_additive_TCC4: OBLIGATION
    FORALL (DX: disjoint_indexed_measurable[T, S], f: integrable[T, S, m]):
      integrable?(IUnion[nat, T](DX))(f);


body:
  %------------------------------------------------------------------------------
  % Measure Contraction
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % If mu is a measure, so is the contraction lambda E: mu(intersection(A,E)).
  %
  % The integrals using the contracted measure are the same as the indefinite
  % integral
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  measure_contraction[T:TYPE,     (IMPORTING subset_algebra_def[T])
                      S:sigma_algebra]: THEORY

  BEGIN

    IMPORTING measure_def[T,S],
              measure_space[T,S]
  ;
    *(f,g:[T -> real]): MACRO [T -> real] = (reals@real_fun_ops[T].*)(f,g)

    mu:  VAR measure_type
    nu:  VAR sigma_finite_measure
    A,E: VAR measurable_set
    f:   VAR measurable_function
    i:   VAR nat

    contraction(mu,A):measure_type = lambda E: mu(intersection(A,E))  % SKB 7.4.2

    fm_contraction(mu:measure_type,A:{E | mu(E)`1}):finite_measure
      = lambda E: mu(intersection(A,E))`2

    sigma_finite_contraction_def: LEMMA
      x_eq(nu(E),x_sum(LAMBDA i: (TRUE,fm_contraction(nu,A_of(nu)(i))(E))))

    IMPORTING isf,
              nn_integral,
              integral,
              indefinite_integral, % Proof only
              integral_convergence % Proof only

    contraction_is_sigma_finite:
                        JUDGEMENT contraction(nu,A) HAS_TYPE sigma_finite_measure

    contraction_isf: LEMMA FORALL (f:simple):
      isf?[T,S,contraction(mu,A)](f) <=> isf?[T,S,mu](phi[T,S](A)*f)

    contraction_isf_integral: LEMMA
      FORALL (f:isf[T,S,contraction(mu,A)]):
        isf_integral[T,S,contraction(mu,A)](f)
          = isf_integral[T,S,mu](phi[T,S](A)*f)

    contraction_nn_integrable: LEMMA FORALL (f:nn_measurable):
      nn_integrable?[T,S,contraction(mu,A)](f) <=>
      nn_integrable?[T,S,mu](phi[T,S](A)*f)

    contraction_nn_integral: LEMMA
      FORALL (f:nn_integrable[T,S,contraction(mu,A)]):
      nn_integral[T,S,contraction(mu,A)](f) = nn_integral[T,S,mu](phi[T,S](A)*f)

    contraction_integrable: LEMMA                                     % SKB 7.4.4
      integrable?[T,S,contraction(mu,A)](f)
        <=> integrable?[T,S,mu](phi[T,S](A)*f)

    contraction_integral:   LEMMA                                     % SKB 7.4.4
      FORALL (f:integrable[T,S,contraction(mu,A)]):
      integral[T,S,contraction(mu,A)](f) = integral[T,S,mu](phi[T,S](A)*f)

  END measure_contraction

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 30, column 48) for  intersection(A, E)
      % expected type  (S)
  contraction_TCC1: OBLIGATION
    FORALL (A: measurable_set[T, S], E): S(intersection[T](A, E));

  % Subtype TCC generated (at line 30, column 35) for
      % LAMBDA E: mu(intersection(A, E))
      % expected type  measure_type[T, S]
  contraction_TCC2: OBLIGATION
    FORALL (x: set[T]): measurable_set?[T, S](x) IFF S(x);

  % Subtype TCC generated (at line 30, column 35) for
      % LAMBDA E: mu(intersection(A, E))
      % expected type  measure_type[T, S]
  contraction_TCC3: OBLIGATION
    FORALL (mu: measure_type[T, S], A: measurable_set[T, S]):
      measure?[T, S](LAMBDA E: mu(intersection[T](A, E)));

  % Subtype TCC generated (at line 32, column 43) for  E
      % expected type  (S)
  fm_contraction_TCC1: OBLIGATION FORALL (E: measurable_set[T, S]): S(E);

  % Subtype TCC generated (at line 33, column 6) for
      % LAMBDA E: mu(intersection(A, E))`2
      % expected type  finite_measure[T, S]
  fm_contraction_TCC2: OBLIGATION
    FORALL (mu: measure_type[T, S], A: {E | mu(E)`1}):
      finite_measure?[T, S](LAMBDA E: mu(intersection[T](A, E))`2);

  % Subtype TCC generated (at line 36, column 55) for  A_of(nu)(i)
      % expected type  {E | nu(E)`1}
  sigma_finite_contraction_def_TCC1: OBLIGATION
    FORALL (nu: sigma_finite_measure[T, S], i):
      measurable_set?[T, S](A_of[T, S](nu)(i)) AND nu(A_of[T, S](nu)(i))`1;

  % Judgement subtype TCC generated (at line 45, column 32) for
      % contraction(nu, A)
      % expected type  sigma_finite_measure[T, S]
  contraction_is_sigma_finite: OBLIGATION
    FORALL (A, nu): sigma_finite_measure?[T, S](contraction(nu, A));

  % Subtype TCC generated (at line 22, column 42) for
      % ((reals@real_fun_ops[T].*)(phi[T, S](A), f))
      % expected type  isf[T, S, mu]
  contraction_isf_integral_TCC1: OBLIGATION
    FORALL (A: measurable_set[T, S], mu: measure_type[T, S],
            f: isf[T, S, contraction(mu, A)]):
      isf?[T, S, mu](((reals@real_fun_ops[T].*)(phi[T, S](A), f)));

  % Subtype TCC generated (at line 56, column 42) for  f
      % expected type  [T -> nnreal]
  contraction_nn_integrable_TCC1: OBLIGATION
    FORALL (f: nn_measurable[T, S]): FORALL (x1: T): f(x1) >= 0;

  % Subtype TCC generated (at line 22, column 42) for
      % ((reals@real_fun_ops[T].*)(phi[T, S](A), f))
      % expected type  [T -> nnreal]
  contraction_nn_integrable_TCC2: OBLIGATION
    FORALL (A: measurable_set[T, S], f: nn_measurable[T, S]):
      FORALL (x1: T): ((reals@real_fun_ops[T].*)(phi[T, S](A), f))(x1) >= 0;

  % Subtype TCC generated (at line 22, column 42) for
      % ((reals@real_fun_ops[T].*)(phi[T, S](A), f))
      % expected type  nn_integrable[T, S, mu]
  contraction_nn_integral_TCC1: OBLIGATION
    FORALL (A: measurable_set[T, S], mu: measure_type[T, S],
            f: nn_integrable[T, S, contraction(mu, A)]):
      (FORALL (x1: T): ((reals@real_fun_ops[T].*)(phi[T, S](A), f))(x1) >= 0)
       AND
       nn_integrable?[T, S, mu](((reals@real_fun_ops[T].*)(phi[T, S](A), f)));

  % Subtype TCC generated (at line 22, column 42) for
      % ((reals@real_fun_ops[T].*)(phi[T, S](A), f))
      % expected type  integrable[T, S, mu]
  contraction_integral_TCC1: OBLIGATION
    FORALL (A: measurable_set[T, S], mu: measure_type[T, S],
            f: integrable[T, S, contraction(mu, A)]):
      integrable?[T, S, mu](((reals@real_fun_ops[T].*)(phi[T, S](A), f)));


body:
  %------------------------------------------------------------------------------
  % Measure Contraction Properties 
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % Decomposition of an integral into a
  %   sequence of integrals over measures contractions
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  measure_contraction_props[T:TYPE,          (IMPORTING subset_algebra_def[T])
                            S:sigma_algebra, (IMPORTING measure_def[T,S])
                            mu:measure_type]: THEORY

  BEGIN

    IMPORTING measure_props[T,S,mu],
              measure_contraction[T,S],
              integral_convergence_scaf % Proof only

    A: VAR disjoint_indexed_measurable
    h: VAR measurable_function
    x: VAR T
    n: VAR nat

    convergent?: MACRO pred[sequence[real]] = topological_convergence.convergent?

    contraction_integrable_def: LEMMA
      IUnion(A) = fullset[T] AND
      (FORALL x:  h(x) >= 0) =>
      (integrable?[T,S,mu](h) <=>
       ((FORALL n: integrable?[T,S,contraction(mu,A(n))](h)) AND
        convergent?(series(lambda n: integral[T,S,contraction(mu,A(n))](h)))))

  END measure_contraction_props

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 33, column 48) for  A(n)
      % expected type  measurable_set[T, S]
  contraction_integrable_def_TCC1: OBLIGATION
    FORALL (A: disjoint_indexed_measurable[T, S],
            h: measurable_function[T, S]):
      (FORALL x: h(x) >= 0) AND IUnion(A) = fullset[T] IMPLIES
       (FORALL (n): measurable_set?[T, S](A(n)));

  % Subtype TCC generated (at line 34, column 70) for  h
      % expected type  integrable[T, S, contraction(mu, A(n))]
  contraction_integrable_def_TCC2: OBLIGATION
    FORALL (A: disjoint_indexed_measurable[T, S],
            h: measurable_function[T, S]):
      ((FORALL x: h(x) >= 0) AND
        IUnion(A) = fullset[T] AND
         (FORALL n: integrable?[T, S, contraction(mu, A(n))](h)))
       IMPLIES
       (FORALL (n1): integrable?[T, S, contraction[T, S](mu, A(n1))](h));


body:
  %------------------------------------------------------------------------------
  % Properties of sigma-finite measures
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  sigma_finite_measure_props[T:TYPE,          (IMPORTING subset_algebra_def[T])
                             S:sigma_algebra, (IMPORTING measure_def[T,S])
                             mu:sigma_finite_measure]: THEORY

  BEGIN

    IMPORTING measure_contraction_props[T,S,mu],
              measure_equality[T,S]

    f: VAR nn_integrable[T,S,mu]
    g: VAR integrable[T,S,mu]
    h: VAR nn_measurable[T,S]
    A: VAR (S)
    x: VAR T
    n: VAR nat
    F: VAR sequence[[T->real]]

    convergent?: MACRO pred[sequence[real]] = topological_convergence.convergent?

    sfm_integrable: LEMMA
      ((FORALL n: integrable?[T,S,contraction(mu,A_of(mu)(n))](h)) AND
       convergent?(series(lambda n:
                            integral[T,S,contraction(mu,A_of(mu)(n))](h))))
      <=> integrable?[T,S,mu](h)

    sfm_integral: LEMMA
     convergence?(series(lambda n: integral[T,S,contraction(mu,A_of(mu)(n))](f)),
                  integral[T,S,mu](f))

    sfm_component_eq: LEMMA x_eq(to_measure(fm_contraction(mu,A_of(mu)(n)))(A),
                                 contraction(mu,A_of(mu)(n))(A))

    IMPORTING integral_convergence[T,S,mu]

    sfm_monotone_convergence: LEMMA                                       % 7.4.5
      ae_increasing?(F) AND
      (FORALL n,x: F(n)(x) >= 0) AND
      (FORALL n: integrable?[T,S,contraction(mu,P_of(mu)(n))](F(n))) =>
      (((EXISTS g:
           ae_convergence?(F,g)) <=>
           bounded?(lambda n: integral[T,S,contraction(mu,P_of(mu)(n))](F(n))))
                                                                              AND
         FORALL g:
           ae_convergence?(F,g) =>
           converges_upto?(lambda n:
                   integral[T,S,contraction(mu,P_of(mu)(n))](F(n)), integral(g)))

  END sigma_finite_measure_props

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 32, column 47) for  A_of(mu)(n)
      % expected type  measurable_set[T, S]
  sfm_integrable_TCC1: OBLIGATION
    FORALL (n): measurable_set?[T, S](A_of[T, S](mu)(n));

  % Subtype TCC generated (at line 34, column 68) for  h
      % expected type  integrable[T, S, contraction(mu, A_of(mu)(n))]
  sfm_integrable_TCC2: OBLIGATION
    FORALL (h: nn_measurable[T, S]):
      (FORALL n: integrable?[T, S, contraction(mu, A_of(mu)(n))](h)) IMPLIES
       (FORALL (n1):
          integrable?[T, S, contraction[T, S](mu, A_of[T, S](mu)(n1))](h));

  % Subtype TCC generated (at line 38, column 75) for  f
      % expected type  integrable[T, S, contraction(mu, A_of(mu)(n))]
  sfm_integral_TCC1: OBLIGATION
    FORALL (f: nn_integrable[T, S, mu], n):
      integrable?[T, S, contraction[T, S](mu, A_of[T, S](mu)(n))](f);

  % Subtype TCC generated (at line 41, column 60) for  A_of(mu)(n)
      % expected type  {E | mu(E)`1}
  sfm_component_eq_TCC1: OBLIGATION
    FORALL (n: nat):
      measurable_set?[T, S](A_of[T, S](mu)(n)) AND mu(A_of[T, S](mu)(n))`1;

  % Subtype TCC generated (at line 49, column 46) for  P_of(mu)(n)
      % expected type  measurable_set[T, S]
  sfm_monotone_convergence_TCC1: OBLIGATION
    FORALL (F: sequence[[T -> real]]):
      (ae_increasing?(F) AND (FORALL n, x: F(n)(x) >= 0)) IMPLIES
       (FORALL (n1): measurable_set?[T, S](P_of[T, S](mu)(n1)));

  % Subtype TCC generated (at line 52, column 70) for  F(n)
      % expected type  integrable[T, S, contraction(mu, P_of(mu)(n))]
  sfm_monotone_convergence_TCC2: OBLIGATION
    FORALL (F: sequence[[T -> real]]):
      (FORALL n: integrable?[T, S, contraction(mu, P_of(mu)(n))](F(n))) AND
       (FORALL n, x: F(n)(x) >= 0) AND ae_increasing?(F)
       IMPLIES
       (FORALL (n1):
          integrable?[T, S, contraction[T, S](mu, P_of[T, S](mu)(n1))]
              (F(n1)));


body:
  %------------------------------------------------------------------------------
  % Iterated Integrals over [T1,T2]
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  product_integral_def[(IMPORTING subset_algebra_def, measure_def)
         T1,T2: TYPE,
         S1:sigma_algebra[T1],S2:sigma_algebra[T2],
         mu:measure_type[T1,S1], nu:measure_type[T2,S2]]: THEORY

  BEGIN

    IMPORTING integral[T1,S1,mu],
              integral[T2,S2,nu],
              reals@real_fun_ops[[T1,T2]]

    h:  VAR [[T1,T2]->real]
    f:  VAR integrable[T1,S1,mu]
    g:  VAR integrable[T2,S2,nu]
    N1: VAR null_set[T1,S1,mu]
    N2: VAR null_set[T2,S2,nu]
    x:  VAR T1
    y:  VAR T2
    c:  VAR real

    integrable1?(h):bool
      = EXISTS N1,f: FORALL x: NOT member(x,N1) =>
                     integrable?(lambda y: h(x,y)) AND
                     integral(lambda y: h(x,y)) = f(x)

    integrable2?(h):bool
      = EXISTS N2,g: FORALL y: NOT member(y,N2) =>
                     integrable?(lambda x: h(x,y)) AND
                     integral(lambda x: h(x,y)) = g(y)

    integrable1: TYPE+  = (integrable1?) CONTAINING (lambda x,y: 0)
    integrable2: TYPE+  = (integrable2?) CONTAINING (lambda x,y: 0)

    g1,h1: VAR integrable1
    g2,h2: VAR integrable2

    integrable1_zero: LEMMA integrable1?(lambda x,y: 0)
    integrable1_add:  JUDGEMENT +(g1,h1)    HAS_TYPE integrable1
    integrable1_scal: JUDGEMENT *(c,h1)     HAS_TYPE integrable1
    integrable1_opp:  JUDGEMENT -(h1)       HAS_TYPE integrable1
    integrable1_diff: JUDGEMENT -(g1,h1)    HAS_TYPE integrable1
    
    integrable2_zero: LEMMA integrable2?(lambda x,y: 0)
    integrable2_add:  JUDGEMENT +(g2,h2)    HAS_TYPE integrable2
    integrable2_scal: JUDGEMENT *(c,h2)     HAS_TYPE integrable2
    integrable2_opp:  JUDGEMENT -(h2)       HAS_TYPE integrable2
    integrable2_diff: JUDGEMENT -(g2,h2)    HAS_TYPE integrable2

    null_integrable1(h1):[null_set[T1,S1,mu],integrable[T1,S1,mu]]
      = choose({(N1,f) | FORALL x: NOT member(x,N1) =>
                         integrable?(lambda y: h1(x,y)) AND
                         integral(lambda y: h1(x,y)) = f(x)})

    null_integrable2(h2):[null_set[T2,S2,nu],integrable[T2,S2,nu]]
      = choose({(N2,g) | FORALL y: NOT member(y,N2) =>
                         integrable?(lambda x: h2(x,y)) AND
                         integral(lambda x: h2(x,y)) = g(y)})

    null_integral1_def: LEMMA
        (N1,f) = null_integrable1(h1) AND
        (NOT member(x,N1)) =>
        (integrable?(lambda y: h1(x,y)) AND
         integral(lambda y: h1(x,y)) = f(x))

    null_integral2_def: LEMMA
        (N2,g) = null_integrable2(h2) AND
        (NOT member(y,N2)) =>
        (integrable?(lambda x: h2(x,y)) AND
         integral(lambda x: h2(x,y)) = g(y))

    integral1(h1): integrable[T1,S1,mu]
      = lambda x: LET (N1,f) = null_integrable1(h1) IN
                  IF member(x,N1) THEN 0 ELSE f(x) ENDIF

    integral2(h2): integrable[T2,S2,nu]
      = lambda y: LET (N2,g) = null_integrable2(h2) IN
                  IF member(y,N2) THEN 0 ELSE g(y) ENDIF

    integral1_zero: LEMMA integral1(lambda x,y: 0) = lambda x: 0
    integral1_add:  LEMMA ae_eq?(integral1(g1+h1), integral1(g1) + integral1(h1))
    integral1_scal: LEMMA ae_eq?(integral1(c*h1),  c*integral1(h1))
    integral1_opp:  LEMMA ae_eq?(integral1(-(h1)), -integral1(h1))
    integral1_diff: LEMMA ae_eq?(integral1(g1-h1), integral1(g1) - integral1(h1))

    integral2_zero: LEMMA integral2(lambda x,y: 0) = lambda y: 0
    integral2_add:  LEMMA ae_eq?(integral2(g2+h2), integral2(g2) + integral2(h2))
    integral2_scal: LEMMA ae_eq?(integral2(c*h2),  c*integral2(h2))
    integral2_opp:  LEMMA ae_eq?(integral2(-(h2)), -integral2(h2))
    integral2_diff: LEMMA ae_eq?(integral2(g2-h2), integral2(g2) - integral2(h2))

  END product_integral_def

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 15, column 10) for  measure_type[T1, S1]
      % generated from assumption generalized_measure_def.S_empty
  mu_TCC1: OBLIGATION S1(emptyset[T1]);

  % Assuming TCC generated (at line 15, column 34) for  measure_type[T2, S2]
      % generated from assumption generalized_measure_def.S_empty
  nu_TCC1: OBLIGATION S2(emptyset[T2]);

  % Subtype TCC generated (at line 42, column 51) for  (LAMBDA x, y: 0)
      % expected type  integrable1
  integrable1_TCC1: OBLIGATION integrable1?((LAMBDA x, y: 0));

  % Subtype TCC generated (at line 43, column 51) for  (LAMBDA x, y: 0)
      % expected type  integrable2
  integrable2_TCC1: OBLIGATION integrable2?((LAMBDA x, y: 0));

  % Judgement subtype TCC generated (at line 49, column 30) for  g1 + h1
      % expected type  integrable1
  integrable1_add: OBLIGATION
    FORALL (g1, h1): integrable1?((+[[T1, T2]])(g1, h1));

  % Judgement subtype TCC generated (at line 50, column 30) for  c * h1
      % expected type  integrable1
  integrable1_scal: OBLIGATION
    FORALL (c, h1): integrable1?(*[[T1, T2]](c, h1));

  % Judgement subtype TCC generated (at line 51, column 30) for  -h1
      % expected type  integrable1
  integrable1_opp: OBLIGATION FORALL (h1): integrable1?(-h1);

  % Judgement subtype TCC generated (at line 52, column 30) for  g1 - h1
      % expected type  integrable1
  integrable1_diff: OBLIGATION
    FORALL (g1, h1): integrable1?((-[[T1, T2]])(g1, h1));

  % Judgement subtype TCC generated (at line 55, column 30) for  g2 + h2
      % expected type  integrable2
  integrable2_add: OBLIGATION
    FORALL (g2, h2): integrable2?((+[[T1, T2]])(g2, h2));

  % Judgement subtype TCC generated (at line 56, column 30) for  c * h2
      % expected type  integrable2
  integrable2_scal: OBLIGATION
    FORALL (c, h2): integrable2?(*[[T1, T2]](c, h2));

  % Judgement subtype TCC generated (at line 57, column 30) for  -h2
      % expected type  integrable2
  integrable2_opp: OBLIGATION FORALL (h2): integrable2?(-h2);

  % Judgement subtype TCC generated (at line 58, column 30) for  g2 - h2
      % expected type  integrable2
  integrable2_diff: OBLIGATION
    FORALL (g2, h2): integrable2?((-[[T1, T2]])(g2, h2));

  % Subtype TCC generated (at line 61, column 13) for
      % {N1, f |
      %    FORALL x:
      %      NOT member(x, N1) =>
      %       integrable?(LAMBDA y: h1(x, y)) AND
      %        integral(LAMBDA y: h1(x, y)) = f(x)}
      % expected type  p:
                     %   (nonempty?
                     %        [[null_set[T1, S1, mu],
                     %          integrable[T1, S1, mu]]])
  null_integrable1_TCC1: OBLIGATION
    FORALL (h1: integrable1):
      nonempty?[[null_set[T1, S1, mu], integrable[T1, S1, mu]]]
          ({N1, f |
              FORALL x:
                NOT member[T1](x, N1) =>
                 integrable?[T2, S2, nu](LAMBDA y: h1(x, y)) AND
                  integral[T2, S2, nu](LAMBDA y: h1(x, y)) = f(x)});

  % Subtype TCC generated (at line 66, column 13) for
      % {N2, g |
      %    FORALL y:
      %      NOT member(y, N2) =>
      %       integrable?(LAMBDA x: h2(x, y)) AND
      %        integral(LAMBDA x: h2(x, y)) = g(y)}
      % expected type  p:
                     %   (nonempty?
                     %        [[null_set[T2, S2, nu],
                     %          integrable[T2, S2, nu]]])
  null_integrable2_TCC1: OBLIGATION
    FORALL (h2: integrable2):
      nonempty?[[null_set[T2, S2, nu], integrable[T2, S2, nu]]]
          ({N2, g |
              FORALL y:
                NOT member[T2](y, N2) =>
                 integrable?[T1, S1, mu](LAMBDA x: h2(x, y)) AND
                  integral[T1, S1, mu](LAMBDA x: h2(x, y)) = g(y)});

  % Subtype TCC generated (at line 83, column 6) for
      % LAMBDA x:
      %   LET (N1, f) = null_integrable1(h1) IN
      %     IF member(x, N1) THEN 0 ELSE f(x) ENDIF
      % expected type  integrable[T1, S1, mu]
  integral1_TCC1: OBLIGATION
    FORALL (h1: integrable1):
      integrable?[T1, S1, mu]
          (LAMBDA x:
             LET (N1, f) = null_integrable1(h1) IN
               IF member[T1](x, N1) THEN 0 ELSE f(x) ENDIF);

  % Subtype TCC generated (at line 87, column 6) for
      % LAMBDA y:
      %   LET (N2, g) = null_integrable2(h2) IN
      %     IF member(y, N2) THEN 0 ELSE g(y) ENDIF
      % expected type  integrable[T2, S2, nu]
  integral2_TCC1: OBLIGATION
    FORALL (h2: integrable2):
      integrable?[T2, S2, nu]
          (LAMBDA y:
             LET (N2, g) = null_integrable2(h2) IN
               IF member[T2](y, N2) THEN 0 ELSE g(y) ENDIF);


body:
  %------------------------------------------------------------------------------
  % Integrals with finite measure
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  % With finite measures (as in probability), every bounded measurable function
  % is integrable.
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  finite_integral[T:TYPE,          (IMPORTING subset_algebra_def[T])
                  S:sigma_algebra, (IMPORTING measure_def[T,S])
                  mu:finite_measure]: THEORY

  BEGIN

    IMPORTING integral[T,S,to_measure(mu)]

    bounded_measurable_is_integrable:
       JUDGEMENT bounded_measurable SUBTYPE_OF integrable

  END finite_integral

addendum:
  %%% ================ Addendum: generated declarations ================

  % Judgement subtype TCC generated (at line 24, column 15) for  x
      % expected type  integrable[T, S, to_measure(mu)]
  bounded_measurable_is_integrable: OBLIGATION
    FORALL (x: bounded_measurable): integrable?[T, S, to_measure(mu)](x);


body:
  %------------------------------------------------------------------------------
  % Monotone Class Lemma for finite measures
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  monotone_classes[T:TYPE,C:(nonempty?[set[T]])]: THEORY

  BEGIN

    IMPORTING subset_algebra_def[T]

    a,b: VAR (C)
    x:   VAR (generated_sigma_algebra(C))

    IMPORTING measure_def[T,(generated_sigma_algebra(C))],
              sigma_algebra,                                % Proof Only
              measure_props                                 % Proof Only

    monotone_finite_measures: COROLLARY FORALL (nu,mu:finite_measure):    % 4.6.7
      (FORALL a,b: member(intersection(a,b),C))              AND
      (FORALL a:   finite_disjoint_union?(C)(complement(a))) AND
      (FORALL a:   mu(a) = nu(a))                            =>
      (FORALL x:   mu(x) = nu(x))

  END monotone_classes

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 28, column 20) for  a
      % expected type  (generated_sigma_algebra(C))
  monotone_finite_measures_TCC1: OBLIGATION
    (FORALL a: finite_disjoint_union?(C)(complement(a))) AND
     (FORALL a, b: member(intersection(a, b), C))
     IMPLIES (FORALL (a1): generated_sigma_algebra[T](C)(a1));


body:
  % various extras for the standard prelude

  sets_lemmas_aux[T:TYPE]: THEORY

  BEGIN

    x, y: VAR T
    a, b, c: VAR set[T]
    A, B : Var setofsets[T]

    IMPORTING sets_lemmas[T]

    union_complement:        LEMMA union(a,complement(a))        = fullset
    intersection_complement: LEMMA intersection(a,complement(a)) = emptyset
    disjoint_complement:     LEMMA disjoint?(a,complement(a))
    disjoint_commutative:    LEMMA disjoint?(a,b) = disjoint?(b,a)
    disjoint_empty:          LEMMA disjoint?(a,emptyset)
    powerset_fullset:        LEMMA member(a, powerset(a))
    union_diff_inter:        LEMMA union(difference(a,b),intersection(a,b)) = a
    disjoint_diff_inter:     LEMMA disjoint?(difference(a,b),intersection(a,b))
    disjoint_member:         LEMMA disjoint?(a,b) AND member(x,a) IMPLIES
                                                                 NOT member(x,b)

  END sets_lemmas_aux


body:
  %-------------------------------------------------------------------------
  %
  % Finite Measure Theory file.
  %
  %     Author: David Lester, Manchester University
  %
  %
  %     Version 1.0           10/4/05
  %-------------------------------------------------------------------------

  finite_measure[T:TYPE,          (IMPORTING subset_algebra_def[T])
                 S:sigma_algebra, (IMPORTING measure_def[T,S])
                 mu:finite_measure]: THEORY

  BEGIN

    IMPORTING sets_lemmas_aux,             % Proof only,     RWB: was sets_aux@
              sets_aux@indexed_sets_aux[nat,T],
              sigma_algebra[T,S],
              series@series_aux,               % Proof only
              structures@fun_preds_partial[nat,set[T],reals.<=,subset?[T]]

    X:   VAR [nat->(S)]
    A,B: VAR (S)

    fm_emptyset:      LEMMA mu(emptyset) = 0
    fm_convergence:   LEMMA disjoint?(X)
                                 => convergence(series(mu o X), mu(IUnion(X)))
    fm_disjointunion: LEMMA disjoint?(A,B) => mu(union(A,B)) = mu(A) + mu(B)
    fm_complement:    LEMMA mu(complement(A)) = mu(fullset) - mu(A)
    fm_union:         LEMMA mu(union(A,B))
                                          = mu(A) + mu(B) - mu(intersection(A,B))
    fm_intersection:  LEMMA mu(intersection(A,B))
                                          = mu(A) + mu(B) - mu(union(A,B))
    fm_difference:    LEMMA mu(difference(A,B))
                                          = mu(A) - mu(B) + mu(difference(B,A))
    fm_subset:        LEMMA subset?(A,B)   => mu(B) = mu(A) + mu(difference(B,A))
    fm_subset_le:     LEMMA subset?(A,B)   => mu(A) <= mu(B)
    fm_monotone:      LEMMA subset?(A,B)   => mu(A) <= mu(B)              % 2.6.1
    fm_IUnion:        LEMMA increasing?(X) => convergence(mu o X, mu(IUnion(X)))
    fm_IIntersection: LEMMA decreasing?(X)
                                 => convergence(mu o X, mu(IIntersection(X)))

    IMPORTING measure_def[T,S]

    measure_from:measure_type = lambda A: (TRUE,mu(A))

  END finite_measure

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 46, column 30) for  LAMBDA A: (TRUE, mu(A))
      % expected type  measure_type[T, S]
  measure_from_TCC1: OBLIGATION measure?[T, S](LAMBDA A: (TRUE, mu(A)));


body:
  %------------------------------------------------------------------------------
  % Sections of sets
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  product_sections[T1,T2:TYPE]: THEORY

  BEGIN

    X,Y: VAR set[[T1,T2]]
    a:   VAR T1
    b:   VAR T2

    IMPORTING topology@cross_product[T1,T2]

    x_section_emptyset:  LEMMA x_section(emptyset,a) = emptyset
    x_section_complement: LEMMA
      x_section(complement(X),a) = complement(x_section(X,a))
    x_section_union: LEMMA
      x_section(union(X,Y),a) = union(x_section(X,a),x_section(Y,a))
    x_section_intersection: LEMMA
      x_section(intersection(X,Y),a)
        = intersection(x_section(X,a),x_section(Y,a))
    x_section_disjoint: LEMMA
      disjoint?(X,Y) => disjoint?(x_section(X,a),x_section(Y,a))

    y_section_emptyset:  LEMMA y_section(emptyset,b) = emptyset
    y_section_complement: LEMMA
      y_section(complement(X),b) = complement(y_section(X,b))
    y_section_union: LEMMA
      y_section(union(X,Y),b) = union(y_section(X,b),y_section(Y,b))
    y_section_intersection: LEMMA
      y_section(intersection(X,Y),b)
        = intersection(y_section(X,b),y_section(Y,b))
    y_section_disjoint: LEMMA
      disjoint?(X,Y) => disjoint?(y_section(X,b),y_section(Y,b))

  END product_sections


body:
  %------------------------------------------------------------------------------
  % Product sigma algebras
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian, "Fundamentals of Real Analysis"
  % Springer, 1999
  %
  %     Version 1.0            11/09/08  Initial Version
  %------------------------------------------------------------------------------

  product_sigma_def[T1,T2:TYPE]: THEORY

  BEGIN

    IMPORTING subset_algebra_def,
              sigma_algebra,
              topology@cross_product[T1,T2],
              product_sections[T1,T2],
              sets_aux@countable_image % Proof Only

    i,n: VAR nat
    x:  VAR T1
    y:  VAR T2
    X:  VAR set[T1]
    Y:  VAR set[T2]
    NX: VAR (nonempty?[T1])
    NY: VAR (nonempty?[T2])
    Z:  VAR set[[T1,T2]]
    S1: VAR sigma_algebra[T1]
    S2: VAR sigma_algebra[T2]

    measurable_rectangle?(S1,S2)(Z):bool
      = EXISTS X,Y: Z = cross_product(X,Y) AND S1(X) AND S2(Y)

    measurable_rectangle(S1,S2): TYPE+ = (measurable_rectangle?(S1,S2))
                                                             CONTAINING emptyset


    sigma_times(S1,S2):sigma_algebra[[T1,T2]]
      = generated_sigma_algebra(fullset[measurable_rectangle(S1,S2)])

    x_section_measurable:   LEMMA member(Z,sigma_times(S1,S2)) =>
                                  member(x_section(Z,x),S2)
    y_section_measurable:   LEMMA member(Z,sigma_times(S1,S2)) =>
                                  member(y_section(Z,y),S1)

    sigma_cross_projection: LEMMA                                         % 7.2.7
       member(cross_product(NX,NY),sigma_times(S1,S2)) =>
       (member(NX,S1) AND member(NY,S2))

  END product_sigma_def

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 37, column 70) for  emptyset
      % expected type  measurable_rectangle(S1, S2)
  measurable_rectangle_TCC1: OBLIGATION
    FORALL (S1: sigma_algebra[T1], S2: sigma_algebra[T2]):
      measurable_rectangle?(S1, S2)(emptyset[[T1, T2]]);


body:
  %------------------------------------------------------------------------------
  % Product sigma algebras
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian, "Fundamentals of Real Analysis"
  % Springer, 1999
  %
  %     Version 1.0            11/09/08  Initial Version
  %------------------------------------------------------------------------------

  product_sigma[T1,T2:TYPE, (IMPORTING subset_algebra_def)
                S1:sigma_algebra[T1],
                S2:sigma_algebra[T2]]: THEORY

  BEGIN

    IMPORTING subset_algebra_def,
              sigma_algebra,
              topology@cross_product[T1,T2],
              product_sigma_def[T1,T2],
              sets_aux@countable_image % Proof Only

    n,i: VAR nat
    X: VAR (S1)
    Y: VAR (S2)
    x: VAR T1
    y: VAR T2
    Z: VAR set[[T1,T2]]
    NX: VAR (nonempty?[T1])
    NY: VAR (nonempty?[T2])
    R,R1,R2: VAR set[(measurable_rectangle?(S1,S2))]
    r,r1,r2: VAR (measurable_rectangle?(S1,S2))

    cross_product_is_sigma_times: LEMMA sigma_times(S1,S2)(cross_product(X,Y))

    rectangle_algebra_aux: LEMMA
      generated_subset_algebra[[T1,T2]](measurable_rectangle?(S1,S2))
        = finite_disjoint_unions[[T1,T2]](measurable_rectangle?(S1,S2))

    rectangle_algebra:subset_algebra[[T1,T2]]                        % SKB 7.2.2
      = finite_disjoint_unions[[T1,T2]](measurable_rectangle?(S1,S2))

    rectangle_algebra_def: LEMMA
      rectangle_algebra
        = generated_subset_algebra[[T1,T2]](measurable_rectangle?(S1,S2))

    finite_disjoint_rectangles: LEMMA
      finite_disjoint_unions[[T1,T2]](measurable_rectangle?(S1,S2))(Z) <=>
      EXISTS R: Union(R) = Z  AND is_finite(R) AND
             FORALL (x,y:(R)): x = y OR disjoint?(x,y)

    intersection_rectangle: LEMMA
      finite_disjoint_union?(measurable_rectangle?(S1,S2))(intersection(r1,r2))

    complement_rectangle:   LEMMA
      finite_disjoint_union?(measurable_rectangle?(S1,S2))(complement(r))

  END product_sigma

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 42, column 6) for
      % finite_disjoint_unions[[T1, T2]](measurable_rectangle?(S1, S2))
      % expected type  subset_algebra[[T1, T2]]
  rectangle_algebra_TCC1: OBLIGATION
    subset_algebra?[[T1, T2]]
        (finite_disjoint_unions[[T1, T2]]
             (measurable_rectangle?[T1, T2](S1, S2)));


body:
  %------------------------------------------------------------------------------
  % Product of two finite measures
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  % How to get a finite measure for sets of [T1,T2], given mu and nu
  % (finite measures for T1 and T2 respectively).
  %
  % Suppose that mu=nu and T1=T2=real. Then fm_times(mu,nu) has to be able to
  % calculate the measure (i.e. area) of a circle; not just for rectangles.
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  product_finite_measure[(IMPORTING subset_algebra_def)
                         T1,T2:TYPE, 
                         S1:sigma_algebra[T1], S2:sigma_algebra[T2]]: THEORY

  BEGIN

    IMPORTING product_sigma_def[T1,T2],
              product_sigma[T1,T2,S1,S2],
              measure_def[T1,S1],
              measure_def[T2,S2],
              measure_def[[T1,T2],sigma_times(S1,S2)],
              integral,
              finite_measure,
              monotone_classes,        % Proof only
              integral_convergence     % Proof only

    M: VAR (sigma_times(S1,S2))
    x: VAR T1
    y: VAR T2
    X: VAR (S1)
    Y: VAR (S2)
    E: VAR sequence[(sigma_times(S1,S2))]
    mu: VAR finite_measure[T1,S1]
    nu: VAR finite_measure[T2,S2]

    x_section_bounded: LEMMA 0 <= (nu o x_section(M))(x) AND        % SKB 7.2.9
                             (nu o x_section(M))(x) <= nu(fullset[T2])
    y_section_bounded: LEMMA 0 <= (mu o y_section(M))(y) AND        % SKB 7.2.9
                             (mu o y_section(M))(y) <= mu(fullset[T1])

    x_section_measurable: LEMMA measurable_function?[T1,S1](nu o x_section(M))
    y_section_measurable: LEMMA measurable_function?[T2,S2](mu o y_section(M))
                                                                     % SKB 7.2.10
    x_section_integrable: LEMMA
      integrable?[T1,S1,to_measure(mu)](nu o x_section(M))
    y_section_integrable: LEMMA
      integrable?[T2,S2,to_measure(nu)](mu o y_section(M))

    rectangle_measure1: LEMMA M = cross_product(X,Y) =>
          integral[T1,S1,to_measure(mu)](nu o x_section(M)) = mu(X)*nu(Y)
    rectangle_measure2: LEMMA M = cross_product(X,Y) =>
          integral[T2,S2,to_measure(nu)](mu o y_section(M)) = mu(X)*nu(Y)

    fm_times(mu,nu):finite_measure[[T1,T2],sigma_times(S1,S2)]
      = lambda M: integral[T1,S1,to_measure(mu)](nu o x_section(M))

    fm_times_alt: LEMMA finite_measure?[[T1,T2],sigma_times(S1,S2)]
         (lambda M: integral[T2,S2,to_measure(nu)](mu o y_section(M)))

    finite_product_alt: THEOREM                                      % SKB 7.2.11
      fm_times(mu,nu)(M) = integral[T2,S2,to_measure(nu)](mu o y_section(M))

  END product_finite_measure

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 43, column 38) for  x_section(M)
      % expected type  [T1 -> (S2)]
  x_section_bounded_TCC1: OBLIGATION
    FORALL (M: (sigma_times(S1, S2)), x1: T1): S2(x_section[T1, T2](M)(x1));

  % Subtype TCC generated (at line 45, column 38) for  y_section(M)
      % expected type  [T2 -> (S1)]
  y_section_bounded_TCC1: OBLIGATION
    FORALL (M: (sigma_times(S1, S2)), x1: T2): S1(y_section[T1, T2](M)(x1));

  % Subtype TCC generated (at line 57, column 39) for  nu o x_section(M)
      % expected type  integrable[T1, S1, to_measure(mu)]
  rectangle_measure1_TCC1: OBLIGATION
    FORALL (M: (sigma_times(S1, S2)), X: (S1), Y: (S2),
            mu: finite_measure[T1, S1], nu: finite_measure[T2, S2]):
      M = cross_product(X, Y) IMPLIES
       integrable?[T1, S1, to_measure[T1, S1](mu)]
           (o[T1, (S2), nnreal](nu, x_section[T1, T2](M)));

  % Subtype TCC generated (at line 59, column 39) for  mu o y_section(M)
      % expected type  integrable[T2, S2, to_measure(nu)]
  rectangle_measure2_TCC1: OBLIGATION
    FORALL (M: (sigma_times(S1, S2)), X: (S1), Y: (S2),
            mu: finite_measure[T1, S1], nu: finite_measure[T2, S2]):
      M = cross_product(X, Y) IMPLIES
       integrable?[T2, S2, to_measure[T2, S2](nu)]
           (o[T2, (S1), nnreal](mu, y_section[T1, T2](M)));

  % Subtype TCC generated (at line 62, column 47) for  nu o x_section(M)
      % expected type  integrable[T1, S1, to_measure(mu)]
  fm_times_TCC1: OBLIGATION
    FORALL (mu: finite_measure[T1, S1], nu: finite_measure[T2, S2], M):
      integrable?[T1, S1, to_measure[T1, S1](mu)]
          (o[T1, (S2), nnreal](nu, x_section[T1, T2](M)));

  % Subtype TCC generated (at line 62, column 16) for
      % integral[T1, S1, to_measure(mu)](nu o x_section(M))
      % expected type  nnreal
  fm_times_TCC2: OBLIGATION
    FORALL (mu: finite_measure[T1, S1], nu: finite_measure[T2, S2], M):
      integral[T1, S1, to_measure[T1, S1](mu)]
          (o[T1, (S2), nnreal](nu, x_section[T1, T2](M)))
       >= 0;

  % Subtype TCC generated (at line 62, column 6) for
      % LAMBDA M: integral[T1, S1, to_measure(mu)](nu o x_section(M))
      % expected type  finite_measure[[T1, T2], sigma_times(S1, S2)]
  fm_times_TCC3: OBLIGATION
    FORALL (mu: finite_measure[T1, S1], nu: finite_measure[T2, S2]):
      finite_measure?[[T1, T2], sigma_times(S1, S2)]
          (LAMBDA M:
             integral[T1, S1, to_measure[T1, S1](mu)]
                 (o[T1, (S2), nnreal](nu, x_section[T1, T2](M))));

  % Subtype TCC generated (at line 65, column 49) for  mu o y_section(M)
      % expected type  integrable[T2, S2, to_measure(nu)]
  fm_times_alt_TCC1: OBLIGATION
    FORALL (mu: finite_measure[T1, S1], nu: finite_measure[T2, S2], M):
      integrable?[T2, S2, to_measure[T2, S2](nu)]
          (o[T2, (S1), nnreal](mu, y_section[T1, T2](M)));

  % Subtype TCC generated (at line 65, column 18) for
      % integral[T2, S2, to_measure(nu)](mu o y_section(M))
      % expected type  nnreal
  fm_times_alt_TCC2: OBLIGATION
    FORALL (mu: finite_measure[T1, S1], nu: finite_measure[T2, S2], M):
      integral[T2, S2, to_measure[T2, S2](nu)]
          (o[T2, (S1), nnreal](mu, y_section[T1, T2](M)))
       >= 0;


body:
  %------------------------------------------------------------------------------
  % Auxilliary results required by Fubini's Theorems for finite measures
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  % Properties of iterated integration with finite measures and simple functions
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  finite_fubini_scaf[(IMPORTING subset_algebra_def, measure_def)
                     T1,T2: TYPE,
                     S1:sigma_algebra[T1],S2:sigma_algebra[T2],
                     mu:finite_measure[T1,S1], nu:finite_measure[T2,S2]]: THEORY

  BEGIN

    IMPORTING product_sigma[T1,T2,S1,S2],
              measure_def[T1,S1],
              measure_def[T2,S2],
              measure_def[[T1,T2],sigma_times(S1,S2)],
              product_finite_measure[T1,T2,S1,S2]

    IMPORTING nn_integral[[T1,T2],sigma_times(S1,S2),to_measure(fm_times(mu,nu))]

    g: VAR nn_integrable
    i: VAR isf
    n: VAR nn_isf
    E: VAR (sigma_times(S1,S2))

    IMPORTING integral[[T1,T2],sigma_times(S1,S2),to_measure(fm_times(mu,nu))]

    f: VAR integrable
    h: VAR nn_measurable[[T1,T2],sigma_times(S1,S2)]
    m: VAR measurable_function[[T1,T2],sigma_times(S1,S2)]
    x: VAR T1
    y: VAR T2

    IMPORTING integral[T1,S1,to_measure(mu)],
              integral[T2,S2,to_measure(nu)]

    measurable_x_section: LEMMA measurable_function?[T2,S2](lambda y: m(x,y))
    measurable_y_section: LEMMA measurable_function?[T1,S1](lambda x: m(x,y))

    isf_x_section:  LEMMA isf?(lambda y: i(x,y)) % 7.3.4 (i)
    isf_y_section:  LEMMA isf?(lambda x: i(x,y)) % 7.3.4 (i)

    integral_phi1: LEMMA  % 7.3.4 (i)
      (lambda x: isf_integral[T2,S2,to_measure(nu)](lambda y: phi(E)(x,y))) = 
        nu o x_section(E)

    integral_phi2: LEMMA  % 7.3.4 (i)
      (lambda y: isf_integral[T1,S1,to_measure(mu)](lambda x: phi(E)(x,y))) = 
        o[T2,(S1),nnreal](mu,y_section(E))

    integral_phi3: LEMMA % 7.3.4 (i)
      isf_integral(phi(E))
        = integral(lambda x: isf_integral(lambda y: phi(E)(x,y)))

    integral_phi4: LEMMA % 7.3.4 (i)
      isf_integral(phi(E))
        = integral(lambda y: isf_integral(lambda x: phi(E)(x,y)))

    isf_integral_x: LEMMA integrable?(lambda x: isf_integral(lambda y: i(x,y)))
    isf_integral_y: LEMMA integrable?(lambda y: isf_integral(lambda x: i(x,y)))

    isf_fubini_tonelli_3: LEMMA
      isf_integral(i) = integral(lambda x: isf_integral(lambda y: i(x,y)))

    isf_fubini_tonelli_4: LEMMA
      isf_integral(i) = integral(lambda y: isf_integral(lambda x: i(x,y)))

  END finite_fubini_scaf

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 17, column 22) for  finite_measure[T1, S1]
      % generated from assumption generalized_measure_def.S_empty
  mu_TCC1: OBLIGATION S1(emptyset[T1]);

  % Assuming TCC generated (at line 17, column 48) for  finite_measure[T2, S2]
      % generated from assumption generalized_measure_def.S_empty
  nu_TCC1: OBLIGATION S2(emptyset[T2]);

  % Subtype TCC generated (at line 52, column 50) for  LAMBDA y: phi(E)(x, y)
      % expected type  isf[T2, S2, to_measure(nu)]
  integral_phi1_TCC1: OBLIGATION
    FORALL (E: (sigma_times(S1, S2)), x):
      isf?[T2, S2, to_measure(nu)]
          (LAMBDA y: phi[[T1, T2], sigma_times(S1, S2)](E)(x, y));

  % Subtype TCC generated (at line 53, column 11) for  x_section(E)
      % expected type  [T1 -> (S2)]
  integral_phi1_TCC2: OBLIGATION
    FORALL (E: (sigma_times(S1, S2)), x1: T1): S2(x_section[T1, T2](E)(x1));

  % Subtype TCC generated (at line 56, column 50) for  LAMBDA x: phi(E)(x, y)
      % expected type  isf[T1, S1, to_measure(mu)]
  integral_phi2_TCC1: OBLIGATION
    FORALL (E: (sigma_times(S1, S2)), y):
      isf?[T1, S1, to_measure(mu)]
          (LAMBDA x: phi[[T1, T2], sigma_times(S1, S2)](E)(x, y));

  % Subtype TCC generated (at line 57, column 27) for  y_section(E)
      % expected type  [T2 -> (S1)]
  integral_phi2_TCC2: OBLIGATION
    FORALL (E: (sigma_times(S1, S2)), x1: T2): (S1)(y_section[T1, T2](E)(x1));

  % Subtype TCC generated (at line 60, column 17) for  phi(E)
      % expected type  isf
                     %     [[T1, T2], sigma_times(S1, S2),
                     %      to_measure(fm_times(mu, nu))]
  integral_phi3_TCC1: OBLIGATION
    FORALL (E: (sigma_times(S1, S2))):
      isf?[[T1, T2], sigma_times(S1, S2), to_measure(fm_times(mu, nu))]
          (phi[[T1, T2], sigma_times(S1, S2)](E));

  % Subtype TCC generated (at line 61, column 17) for
      % LAMBDA x: isf_integral(LAMBDA y: phi(E)(x, y))
      % expected type  integrable[T1, S1, to_measure(mu)]
  integral_phi3_TCC2: OBLIGATION
    FORALL (E: (sigma_times(S1, S2))):
      integrable?[T1, S1, to_measure(mu)]
          (LAMBDA x:
             isf_integral[T2, S2, to_measure(nu)]
                 (LAMBDA y: phi[[T1, T2], sigma_times(S1, S2)](E)(x, y)));

  % Subtype TCC generated (at line 65, column 17) for
      % LAMBDA y: isf_integral(LAMBDA x: phi(E)(x, y))
      % expected type  integrable[T2, S2, to_measure(nu)]
  integral_phi4_TCC1: OBLIGATION
    FORALL (E: (sigma_times(S1, S2))):
      integrable?[T2, S2, to_measure(nu)]
          (LAMBDA y:
             isf_integral[T1, S1, to_measure(mu)]
                 (LAMBDA x: phi[[T1, T2], sigma_times(S1, S2)](E)(x, y)));

  % Subtype TCC generated (at line 67, column 59) for  LAMBDA y: i(x, y)
      % expected type  isf[T2, S2, to_measure(nu)]
  isf_integral_x_TCC1: OBLIGATION
    FORALL (i:
              isf
                  [[T1, T2], sigma_times(S1, S2),
                   to_measure(fm_times(mu, nu))],
            x):
      isf?[T2, S2, to_measure(nu)](LAMBDA y: i(x, y));

  % Subtype TCC generated (at line 68, column 59) for  LAMBDA x: i(x, y)
      % expected type  isf[T1, S1, to_measure(mu)]
  isf_integral_y_TCC1: OBLIGATION
    FORALL (i:
              isf
                  [[T1, T2], sigma_times(S1, S2),
                   to_measure(fm_times(mu, nu))],
            y):
      isf?[T1, S1, to_measure(mu)](LAMBDA x: i(x, y));

  % Subtype TCC generated (at line 71, column 31) for
      % LAMBDA x: isf_integral(LAMBDA y: i(x, y))
      % expected type  integrable[T1, S1, to_measure(mu)]
  isf_fubini_tonelli_3_TCC1: OBLIGATION
    FORALL (i:
              isf
                  [[T1, T2], sigma_times(S1, S2),
                   to_measure(fm_times(mu, nu))]):
      integrable?[T1, S1, to_measure(mu)]
          (LAMBDA x: isf_integral[T2, S2, to_measure(nu)](LAMBDA y: i(x, y)));

  % Subtype TCC generated (at line 74, column 31) for
      % LAMBDA y: isf_integral(LAMBDA x: i(x, y))
      % expected type  integrable[T2, S2, to_measure(nu)]
  isf_fubini_tonelli_4_TCC1: OBLIGATION
    FORALL (i:
              isf
                  [[T1, T2], sigma_times(S1, S2),
                   to_measure(fm_times(mu, nu))]):
      integrable?[T2, S2, to_measure(nu)]
          (LAMBDA y: isf_integral[T1, S1, to_measure(mu)](LAMBDA x: i(x, y)));


body:
  %------------------------------------------------------------------------------
  % Fubini-Tonelli Theorems for finite measures
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  % Properties of iterated integration with finite measures and measurable
  % functions
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  finite_fubini_tonelli[(IMPORTING subset_algebra_def, measure_def)
                T1,T2: TYPE,
                S1:sigma_algebra[T1],S2:sigma_algebra[T2],
                mu:finite_measure[T1,S1],
                nu:finite_measure[T2,S2]]: THEORY

  BEGIN

    IMPORTING finite_fubini_scaf[T1,T2,S1,S2,mu,nu],
              product_integral_def[T1,T2,S1,S2,to_measure(mu),to_measure(nu)],
              integral_convergence, % Proof only
              indefinite_integral   % Proof only

    g: VAR nn_integrable[[T1,T2],sigma_times(S1,S2),to_measure(fm_times(mu,nu))]
    h: VAR nn_measurable[[T1,T2],sigma_times(S1,S2)]

    finite_fubini_tonelli_1: LEMMA integrable?(h) <=> integrable1?(h)     % 7.3.6

    finite_fubini_tonelli_2: LEMMA integrable?(h) <=> integrable2?(h)     % 7.3.6

    finite_fubini_tonelli_3: LEMMA integral(g) = integral(integral1(g))   % 7.3.6

    finite_fubini_tonelli_4: LEMMA integral(g) = integral(integral2(g))   % 7.3.6

  END finite_fubini_tonelli

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 18, column 17) for  finite_measure[T1, S1]
      % generated from assumption generalized_measure_def.S_empty
  mu_TCC1: OBLIGATION S1(emptyset[T1]);

  % Assuming TCC generated (at line 19, column 17) for  finite_measure[T2, S2]
      % generated from assumption generalized_measure_def.S_empty
  nu_TCC1: OBLIGATION S2(emptyset[T2]);

  % Subtype TCC generated (at line 35, column 66) for  g
      % expected type  integrable1
                     %     [T1, T2, S1, S2, to_measure(mu), to_measure(nu)]
  finite_fubini_tonelli_3_TCC1: OBLIGATION
    FORALL (g:
              nn_integrable
                  [[T1, T2], sigma_times(S1, S2),
                   to_measure(fm_times(mu, nu))]):
      integrable1?[T1, T2, S1, S2, to_measure(mu), to_measure(nu)](g);

  % Subtype TCC generated (at line 37, column 66) for  g
      % expected type  integrable2
                     %     [T1, T2, S1, S2, to_measure(mu), to_measure(nu)]
  finite_fubini_tonelli_4_TCC1: OBLIGATION
    FORALL (g:
              nn_integrable
                  [[T1, T2], sigma_times(S1, S2),
                   to_measure(fm_times(mu, nu))]):
      integrable2?[T1, T2, S1, S2, to_measure(mu), to_measure(nu)](g);


body:
  %------------------------------------------------------------------------------
  % Fubini's Theorems for finite measures
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  % Interchanging the order of integration for finite measures.
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  finite_fubini[(IMPORTING subset_algebra_def,measure_def)
                T1,T2: TYPE,
                S1:sigma_algebra[T1],S2:sigma_algebra[T2],
                mu:finite_measure[T1,S1],
                nu:finite_measure[T2,S2]]: THEORY

  BEGIN

    IMPORTING
     sigma_algebra[T1,S1],
     sigma_algebra[T2,S2],
     finite_fubini_tonelli[T1,T2,S1,S2,mu,nu],
     finite_integral[[T1,T2],sigma_times(S1,S2),fm_times(mu,nu)], % Proof Only
     finite_integral[T1,S1,mu], % Proof Only
     finite_integral[T2,S2,nu]  % Proof Only

    f: VAR integrable[[T1,T2],sigma_times(S1,S2),to_measure(fm_times(mu,nu))]

    finite_integrable_is_integrable1: LEMMA integrable1?(f)               % 7.3.7
    finite_integrable_is_integrable2: LEMMA integrable2?(f)               % 7.3.7

    finite_fubini1: COROLLARY integral(f) = integral(integral1(f))        % 7.3.7
    finite_fubini2: COROLLARY integral(f) = integral(integral2(f))        % 7.3.7

    h: VAR bounded_measurable[[T1,T2],sigma_times(S1,S2)]
    x: VAR T1
    y: VAR T2

    integrable_x_section: LEMMA integrable?(lambda y: h(x,y))             % 7.3.8
    integrable_y_section: LEMMA integrable?(lambda x: h(x,y))             % 7.3.8

    integrable_integral_x_section: LEMMA                                  % 7.3.8
      integrable?(lambda x: integral(lambda y: h(x,y)))
    integrable_integral_y_section: LEMMA                                  % 7.3.8
      integrable?(lambda y: integral(lambda x: h(x,y)))

    integral_integral_x_section: LEMMA                                    % 7.3.8
      integral(lambda x: integral(lambda y: h(x,y))) = integral(h)
    integral_integral_y_section: LEMMA                                    % 7.3.8
      integral(lambda y: integral(lambda x: h(x,y))) = integral(h)

  END finite_fubini

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 17, column 17) for  finite_measure[T1, S1]
      % generated from assumption generalized_measure_def.S_empty
  mu_TCC1: OBLIGATION S1(emptyset[T1]);

  % Assuming TCC generated (at line 18, column 17) for  finite_measure[T2, S2]
      % generated from assumption generalized_measure_def.S_empty
  nu_TCC1: OBLIGATION S2(emptyset[T2]);

  % Subtype TCC generated (at line 35, column 61) for  f
      % expected type  integrable1
                     %     [T1, T2, S1, S2, to_measure(mu), to_measure(nu)]
  finite_fubini1_TCC1: OBLIGATION
    FORALL (f:
              integrable
                  [[T1, T2], sigma_times(S1, S2),
                   to_measure(fm_times(mu, nu))]):
      integrable1?[T1, T2, S1, S2, to_measure(mu), to_measure(nu)](f);

  % Subtype TCC generated (at line 36, column 61) for  f
      % expected type  integrable2
                     %     [T1, T2, S1, S2, to_measure(mu), to_measure(nu)]
  finite_fubini2_TCC1: OBLIGATION
    FORALL (f:
              integrable
                  [[T1, T2], sigma_times(S1, S2),
                   to_measure(fm_times(mu, nu))]):
      integrable2?[T1, T2, S1, S2, to_measure(mu), to_measure(nu)](f);

  % Subtype TCC generated (at line 46, column 35) for  LAMBDA y: h(x, y)
      % expected type  integrable[T2, S2, to_measure(nu)]
  integrable_integral_x_section_TCC1: OBLIGATION
    FORALL (h: bounded_measurable[[T1, T2], sigma_times(S1, S2)], x):
      integrable?[T2, S2, to_measure(nu)](LAMBDA y: h(x, y));

  % Subtype TCC generated (at line 48, column 35) for  LAMBDA x: h(x, y)
      % expected type  integrable[T1, S1, to_measure(mu)]
  integrable_integral_y_section_TCC1: OBLIGATION
    FORALL (h: bounded_measurable[[T1, T2], sigma_times(S1, S2)], y):
      integrable?[T1, S1, to_measure(mu)](LAMBDA x: h(x, y));

  % Subtype TCC generated (at line 51, column 13) for
      % LAMBDA x: integral(LAMBDA y: h(x, y))
      % expected type  integrable[T1, S1, to_measure(mu)]
  integral_integral_x_section_TCC1: OBLIGATION
    FORALL (h: bounded_measurable[[T1, T2], sigma_times(S1, S2)]):
      integrable?[T1, S1, to_measure(mu)]
          (LAMBDA x: integral[T2, S2, to_measure(nu)](LAMBDA y: h(x, y)));

  % Subtype TCC generated (at line 51, column 62) for  h
      % expected type  integrable
                     %     [[T1, T2], sigma_times(S1, S2),
                     %      to_measure(fm_times(mu, nu))]
  integral_integral_x_section_TCC2: OBLIGATION
    FORALL (h: bounded_measurable[[T1, T2], sigma_times(S1, S2)]):
      integrable?[[T1, T2], sigma_times(S1, S2), to_measure(fm_times(mu, nu))]
          (h);

  % Subtype TCC generated (at line 53, column 13) for
      % LAMBDA y: integral(LAMBDA x: h(x, y))
      % expected type  integrable[T2, S2, to_measure(nu)]
  integral_integral_y_section_TCC1: OBLIGATION
    FORALL (h: bounded_measurable[[T1, T2], sigma_times(S1, S2)]):
      integrable?[T2, S2, to_measure(nu)]
          (LAMBDA y: integral[T1, S1, to_measure(mu)](LAMBDA x: h(x, y)));


body:
  %------------------------------------------------------------------------------
  % Product of two sigam-finite measures
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  % Generalizing the results for finite measures to sigma-finite measures.
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------
  product_measure[(IMPORTING subset_algebra_def)
                  T1,T2:TYPE,
                  S1:sigma_algebra[T1], S2:sigma_algebra[T2]]: THEORY
  BEGIN

    IMPORTING product_sigma[T1,T2,S1,S2],
              measure_contraction[T1,S1],
              measure_contraction[T2,S2],
              measure_contraction[[T1,T2],sigma_times(S1,S2)],
              product_finite_measure[T1,T2,S1,S2],
              extended_nnreal@double_index[set[[T1,T2]]] % Proof Only

    mu: VAR sigma_finite_measure[T1,S1]
    nu: VAR sigma_finite_measure[T2,S2]
    X:  VAR (S1)
    Y:  VAR (S2)
    M:  VAR (sigma_times(S1,S2))
    z:  VAR [T1,T2]
    i,j,n:  VAR nat

    product_measure_approx(mu,nu)(i,j):finite_measure[[T1,T2],sigma_times(S1,S2)]
     = fm_times(fm_contraction[T1,S1](mu,A_of(mu)(i)),
                fm_contraction[T2,S2](nu,A_of(nu)(j)))

    m_times(mu,nu):sigma_finite_measure[[T1,T2],sigma_times(S1,S2)]      % 7.2.12
       = lambda M:
           x_sum(lambda i: x_sum(lambda j:
                  to_measure(product_measure_approx(mu,nu)(i,j))(M)))

    m_times_alt: LEMMA
       x_eq(m_times(mu,nu)(M),
            x_sum(lambda j: x_sum(lambda i:
                             to_measure(product_measure_approx(mu,nu)(i,j))(M))))

    rectangle_measure: LEMMA
      x_eq(m_times(mu,nu)(cross_product(X,Y)),x_times(mu(X),nu(Y)))

    phi1(X):simple[[T1,T2],sigma_times(S1,S2)]= phi(cross_product(X,fullset[T2]))
    phi2(Y):simple[[T1,T2],sigma_times(S1,S2)]= phi(cross_product(fullset[T1],Y))

  END product_measure

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 34, column 39) for  A_of(mu)(i)
      % expected type  {E | mu(E)`1}
  product_measure_approx_TCC1: OBLIGATION
    FORALL (mu: sigma_finite_measure[T1, S1], i: nat):
      measurable_set?[T1, S1](A_of[T1, S1](mu)(i)) AND
       mu(A_of[T1, S1](mu)(i))`1;

  % Subtype TCC generated (at line 35, column 39) for  A_of(nu)(j)
      % expected type  {E | nu(E)`1}
  product_measure_approx_TCC2: OBLIGATION
    FORALL (nu: sigma_finite_measure[T2, S2], j: nat):
      measurable_set?[T2, S2](A_of[T2, S2](nu)(j)) AND
       nu(A_of[T2, S2](nu)(j))`1;

  % Subtype TCC generated (at line 38, column 7) for
      % LAMBDA M:
      %   x_sum(LAMBDA i:
      %           x_sum(LAMBDA j:
      %                   to_measure(product_measure_approx(mu, nu)(i, j))
      %                             (M)))
      % expected type  sigma_finite_measure[[T1, T2], sigma_times(S1, S2)]
  m_times_TCC1: OBLIGATION
    FORALL (mu: sigma_finite_measure[T1, S1],
            nu: sigma_finite_measure[T2, S2]):
      sigma_finite_measure?[[T1, T2], sigma_times(S1, S2)]
          (LAMBDA M:
             x_sum(LAMBDA i:
                     x_sum(LAMBDA j:
                             to_measure[[T1, T2], sigma_times(S1, S2)]
                                 (product_measure_approx(mu, nu)(i, j))(M))));

  % Subtype TCC generated (at line 48, column 24) for  cross_product(X, Y)
      % expected type  (sigma_times(S1, S2))
  rectangle_measure_TCC1: OBLIGATION
    FORALL (X: (S1), Y: (S2)):
      sigma_times[T1, T2](S1, S2)(cross_product[T1, T2](X, Y));

  % Subtype TCC generated (at line 50, column 46) for
      % phi(cross_product(X, fullset[T2]))
      % expected type  simple[[T1, T2], sigma_times(S1, S2)]
  phi1_TCC1: OBLIGATION
    FORALL (X: (S1)):
      simple?[[T1, T2], sigma_times(S1, S2)]
          (phi[[T1, T2], sigma_times(S1, S2)]
               (cross_product[T1, T2](X, fullset[T2])));

  % Subtype TCC generated (at line 51, column 46) for
      % phi(cross_product(fullset[T1], Y))
      % expected type  simple[[T1, T2], sigma_times(S1, S2)]
  phi2_TCC1: OBLIGATION
    FORALL (Y: (S2)):
      simple?[[T1, T2], sigma_times(S1, S2)]
          (phi[[T1, T2], sigma_times(S1, S2)]
               (cross_product[T1, T2](fullset[T1], Y)));


body:
  %------------------------------------------------------------------------------
  % Fubini-Tonelli Theorems
  %
  %     Author: David Lester, Manchester University, NIA, Universite Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  %     Version 1.0            5/06/09  Initial Version
  %------------------------------------------------------------------------------

  fubini_tonelli_scaf[(IMPORTING subset_algebra_def, measure_def)
         T1,T2: TYPE,
         S1:sigma_algebra[T1],S2:sigma_algebra[T2],
         mu:sigma_finite_measure[T1,S1],
         nu:sigma_finite_measure[T2,S2]]: THEORY

  BEGIN

    IMPORTING product_measure[T1,T2,S1,S2],
              integral[[T1,T2],sigma_times(S1,S2),m_times(mu,nu)]            

    E:   VAR (sigma_times(S1,S2))
    X:   VAR (S1)
    Y:   VAR (S2)
    x:   VAR T1
    y:   VAR T2
    i,j,n: VAR nat

    IMPORTING product_integral_def[T1,T2,S1,S2,mu,nu],
              measure_contraction_props,
              measure_equality,             % Proof only
              finite_fubini_tonelli,        % Proof Only
              finite_fubini,                % Proof Only
              indefinite_integral,          % Proof only
              extended_nnreal@double_nn_sequence, % Proof only
              sigma_finite_measure_props    % Proof Only

    h: VAR nn_measurable[[T1,T2],sigma_times(S1,S2)]

    IMPORTING product_integral_def,      % Proof only
              sigma_finite_measure_props % Proof only

    convergent?: MACRO pred[sequence[real]] = topological_convergence.convergent?

    product_measure_contraction: LEMMA                                % SKB 7.4.6
      x_eq(contraction(m_times(mu, nu),cross_product(X,Y))(E),
           m_times(contraction(mu,X),contraction(nu,Y))(E))

    product_sfm_contraction: LEMMA
      x_eq(contraction(m_times(mu, nu),
                       cross_product(A_of(mu)(i),A_of(nu)(j)))(E),
           product_measure_approx(mu,nu)(i,j)(E))

    product_measure_contraction_n: LEMMA
      x_eq(m_times(contraction(mu, P_of(mu)(n)),
                   contraction(nu, P_of(nu)(n)))(E),
           to_measure(fm_times(fm_contraction(mu, P_of(mu)(n)),
                               fm_contraction(nu, P_of(nu)(n))))(E))

    fubini_tonelli_scaf1: LEMMA                                           % 7.4.7
      (integrable?(h) <=> integrable1?(h)) AND
      (integrable?(h) => integral(h) = integral(integral1[T1,T2,S1,S2,mu,nu](h)))

    fubini_tonelli_scaf2: LEMMA                                           % 7.4.7
      (integrable?(h) <=> integrable2?(h)) AND
      (integrable?(h) => integral(h) = integral(integral2[T1,T2,S1,S2,mu,nu](h)))

  END fubini_tonelli_scaf

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 47, column 37) for  cross_product(X, Y)
      % expected type  measurable_set[[T1, T2], sigma_times(S1, S2)]
  product_measure_contraction_TCC1: OBLIGATION
    FORALL (X: (S1), Y: (S2)):
      measurable_set?[[T1, T2], sigma_times(S1, S2)]
          (cross_product[T1, T2](X, Y));

  % Subtype TCC generated (at line 48, column 32) for  X
      % expected type  measurable_set[T1, S1]
  product_measure_contraction_TCC2: OBLIGATION
    FORALL (X: (S1)): measurable_set?[T1, S1](X);

  % Subtype TCC generated (at line 48, column 50) for  Y
      % expected type  measurable_set[T2, S2]
  product_measure_contraction_TCC3: OBLIGATION
    FORALL (Y: (S2)): measurable_set?[T2, S2](Y);

  % Subtype TCC generated (at line 52, column 21) for
      % cross_product(A_of(mu)(i), A_of(nu)(j))
      % expected type  measurable_set[[T1, T2], sigma_times(S1, S2)]
  product_sfm_contraction_TCC1: OBLIGATION
    FORALL (i, j: nat):
      measurable_set?[[T1, T2], sigma_times(S1, S2)]
          (cross_product[T1, T2](A_of[T1, S1](mu)(i), A_of[T2, S2](nu)(j)));

  % Subtype TCC generated (at line 56, column 33) for  P_of(mu)(n)
      % expected type  measurable_set[T1, S1]
  product_measure_contraction_n_TCC1: OBLIGATION
    FORALL (n: nat): measurable_set?[T1, S1](P_of[T1, S1](mu)(n));

  % Subtype TCC generated (at line 57, column 33) for  P_of(nu)(n)
      % expected type  measurable_set[T2, S2]
  product_measure_contraction_n_TCC2: OBLIGATION
    FORALL (n: nat): measurable_set?[T2, S2](P_of[T2, S2](nu)(n));

  % Subtype TCC generated (at line 58, column 48) for  P_of(mu)(n)
      % expected type  {E | mu(E)`1}
  product_measure_contraction_n_TCC3: OBLIGATION
    FORALL (n: nat):
      measurable_set?[T1, S1](P_of[T1, S1](mu)(n)) AND
       mu(P_of[T1, S1](mu)(n))`1;

  % Subtype TCC generated (at line 59, column 48) for  P_of(nu)(n)
      % expected type  {E | nu(E)`1}
  product_measure_contraction_n_TCC4: OBLIGATION
    FORALL (n: nat):
      measurable_set?[T2, S2](P_of[T2, S2](nu)(n)) AND
       nu(P_of[T2, S2](nu)(n))`1;

  % Subtype TCC generated (at line 63, column 75) for  h
      % expected type  integrable1[T1, T2, S1, S2, mu, nu]
  fubini_tonelli_scaf1_TCC1: OBLIGATION
    FORALL (h: nn_measurable[[T1, T2], sigma_times(S1, S2)]):
      (integrable1?(h) IMPLIES integrable?(h)) AND
       (integrable?(h) IMPLIES integrable1?(h)) AND integrable?(h)
       IMPLIES integrable1?[T1, T2, S1, S2, mu, nu](h);

  % Subtype TCC generated (at line 67, column 75) for  h
      % expected type  integrable2[T1, T2, S1, S2, mu, nu]
  fubini_tonelli_scaf2_TCC1: OBLIGATION
    FORALL (h: nn_measurable[[T1, T2], sigma_times(S1, S2)]):
      (integrable2?(h) IMPLIES integrable?(h)) AND
       (integrable?(h) IMPLIES integrable2?(h)) AND integrable?(h)
       IMPLIES integrable2?[T1, T2, S1, S2, mu, nu](h);


body:
  %------------------------------------------------------------------------------
  % Fubini-Tonelli Theorems
  %
  %     Author: David Lester, Manchester University, NIA, Universite Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  %     Version 1.0            5/06/09  Initial Version
  %------------------------------------------------------------------------------

  fubini_tonelli[(IMPORTING subset_algebra_def, measure_def)
         T1,T2: TYPE,
         S1:sigma_algebra[T1],S2:sigma_algebra[T2],
         mu:sigma_finite_measure[T1,S1],
         nu:sigma_finite_measure[T2,S2]]: THEORY

  BEGIN

    IMPORTING product_measure[T1,T2,S1,S2],
              integral[[T1,T2],sigma_times(S1,S2),m_times(mu,nu)]            

    g: VAR nn_integrable
    h: VAR nn_measurable[[T1,T2],sigma_times(S1,S2)]
    x: VAR T1
    y: VAR T2

    IMPORTING product_integral_def[T1,T2,S1,S2,mu,nu],
              fubini_tonelli_scaf[T1,T2,S1,S2,mu,nu]

    fubini_tonelli_1: THEOREM integrable?(h) <=> integrable1?(h)          % 7.4.7

    fubini_tonelli_2: THEOREM integrable?(h) <=> integrable2?(h)          % 7.4.7

    fubini_tonelli_3: THEOREM                                             % 7.4.7
       integral(g) = integral(integral1[T1,T2,S1,S2,mu,nu](g))

    fubini_tonelli_4: THEOREM                                             % 7.4.7
       integral(g) = integral(integral2[T1,T2,S1,S2,mu,nu](g))

  END fubini_tonelli

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 36, column 57) for  g
      % expected type  integrable1[T1, T2, S1, S2, mu, nu]
  fubini_tonelli_3_TCC1: OBLIGATION
    FORALL (g:
              nn_integrable[[T1, T2], sigma_times(S1, S2), m_times(mu, nu)]):
      integrable1?[T1, T2, S1, S2, mu, nu](g);

  % Subtype TCC generated (at line 39, column 57) for  g
      % expected type  integrable2[T1, T2, S1, S2, mu, nu]
  fubini_tonelli_4_TCC1: OBLIGATION
    FORALL (g:
              nn_integrable[[T1, T2], sigma_times(S1, S2), m_times(mu, nu)]):
      integrable2?[T1, T2, S1, S2, mu, nu](g);


body:
  %------------------------------------------------------------------------------
  % Fubini-Tonelli Theorems
  %
  %     Author: David Lester, Manchester University, NIA, Universite Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  %     Version 1.0            5/06/09  Initial Version
  %------------------------------------------------------------------------------

  fubini[(IMPORTING subset_algebra_def, measure_def)
         T1,T2: TYPE,
         S1:sigma_algebra[T1],S2:sigma_algebra[T2],
         mu:sigma_finite_measure[T1,S1],
         nu:sigma_finite_measure[T2,S2]]: THEORY

  BEGIN

    IMPORTING fubini_tonelli[T1,T2,S1,S2,mu,nu]

    f: VAR integrable[[T1,T2],sigma_times(S1,S2),m_times(mu,nu)]
    x: VAR T1
    y: VAR T2

    integrable_is_integrable1: LEMMA integrable1?(f)
    integrable_is_integrable2: LEMMA integrable2?(f)

    fubini1: LEMMA integral(f) = integral(integral1[T1,T2,S1,S2,mu,nu](f))
    fubini2: LEMMA integral(f) = integral(integral2[T1,T2,S1,S2,mu,nu](f))

  END fubini

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 29, column 69) for  f
      % expected type  integrable1[T1, T2, S1, S2, mu, nu]
  fubini1_TCC1: OBLIGATION
    FORALL (f: integrable[[T1, T2], sigma_times(S1, S2), m_times(mu, nu)]):
      integrable1?[T1, T2, S1, S2, mu, nu](f);

  % Subtype TCC generated (at line 30, column 69) for  f
      % expected type  integrable2[T1, T2, S1, S2, mu, nu]
  fubini2_TCC1: OBLIGATION
    FORALL (f: integrable[[T1, T2], sigma_times(S1, S2), m_times(mu, nu)]):
      integrable2?[T1, T2, S1, S2, mu, nu](f);


body:
  %-------------------------------------------------------------------------
  % Complete Measure Theory
  %
  %     Author: David Lester, Manchester University
  %
  %     Version 1.0           04/05/09    Initial (DRL)
  %-------------------------------------------------------------------------

  complete_measure_theory[T:TYPE,          (IMPORTING subset_algebra_def[T])
                          S:sigma_algebra, (IMPORTING measure_def[T,S])
                          mu:complete_measure]: THEORY

  BEGIN

    IMPORTING measure_space_def[T,S],
              sigma_algebra[T,S],
              measure_theory[T,S,mu],
              measure_props[T,S,mu]

    N: VAR null_set
    X: VAR set[T]
    E: VAR negligible
    f: VAR [T->real]
    g: VAR measurable_function

    null_subset:        LEMMA subset?(X,N)  => null_set?(X)
    null_is_negligible: LEMMA null_set?(X) <=> negligible_set?(X)
    ae_eq_measurable:   LEMMA ae_eq?(f,g)   => measurable_function?(f)

  END complete_measure_theory

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 17, column 31) for  mu
      % expected type  measure_type[T, S]
  IMP_measure_theory_TCC1: OBLIGATION measure?[T, S](mu);


body:
  %------------------------------------------------------------------------------
  % Properties of integrals with complete measures
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  % Some consequences of complete_integral_ae_eq; compare with the general
  % version of 4.4.16 (for non-complete measures) in integral library.
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  complete_integral[T:TYPE,           (IMPORTING subset_algebra_def[T])
                    S:sigma_algebra,  (IMPORTING measure_def[T,S])
                    mu:complete_measure]: THEORY

  BEGIN

    IMPORTING complete_measure_theory[T,S,mu],
              integral[T,S,mu],
              integral_convergence[T,S,mu]

    f: VAR integrable
    h: VAR [T->real]
    F: VAR sequence[integrable]
    n: VAR nat
    x: VAR T

    complete_integral_ae_eq:  LEMMA ae_eq?(f,h) =>                       % 4.4.16
                                    (integrable?(h) AND
                                     integral(f) = integral(h))

    complete_measurable_ae_0: LEMMA ae_0?(h) =>
                                    (integrable?(h) AND integral(h) = 0)

    monotone_convergence_complete: THEOREM                               % 4.5.3
        ae_monotonic_converges?(F,h) AND bounded?(integral o F) =>
        (integrable?(h) AND monotonic_converges?((integral o F),integral(h)))

    dominated_convergence_complete: THEOREM                              % 4.5.4
      (FORALL n: ae_le?(abs(F(n)),f)) AND ae_convergence?(F,h) =>
      (integrable?(h) AND convergence?(integral o F, integral(h)))

  END complete_integral

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 22, column 25) for  mu
      % expected type  measure_type[T, S]
  IMP_integral_TCC1: OBLIGATION measure?[T, S](mu);


body:
  %------------------------------------------------------------------------------
  % Auxilliary results to complete a measure 
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % Note: not described in Berberian 
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  measure_completion_aux[T:TYPE]: THEORY

  BEGIN

    IMPORTING subset_algebra_def[T],
              measure_def,
              measure_theory,
              measure_props

    XS: VAR setofsets[T]
    A,B,X:  VAR set[T]
    z:  VAR extended_nnreal

    almost_measurable?(S:sigma_algebra[T],m:measure_type[T,S])(X):bool
      = EXISTS (Y:(S),N1,N2:negligible[T,S,m]): X = difference(union(Y,N1),N2)

    empty_almost_measurable: LEMMA
      FORALL (S:sigma_algebra[T],m:measure_type[T,S]):
        almost_measurable?(S,m)(emptyset[T])

    complement_almost_measurable: LEMMA
      FORALL (S:sigma_algebra[T],m:measure_type[T,S]):
        almost_measurable?(S,m)(X) <=> almost_measurable?(S,m)(complement(X))

    Union_almost_measurable: LEMMA
      FORALL (S:sigma_algebra[T],m:measure_type[T,S]):
        every(almost_measurable?(S,m),XS) AND is_countable(XS) =>
              almost_measurable?(S,m)(Union(XS))

    completion(S:sigma_algebra[T],m:measure_type[T,S]):sigma_algebra[T]
      = {X | almost_measurable?(S,m)(X)}

    generated_completion: LEMMA FORALL (S:sigma_algebra[T],m:measure_type[T,S]):
      generated_sigma_algebra(union(S,fullset[negligible[T,S,m]]))
        = completion(S,m)

    completion_extends: LEMMA FORALL (S:sigma_algebra[T],m:measure_type[T,S]):
                              S(X) => completion(S,m)(X)

    negligible_completion: LEMMA FORALL (S:sigma_algebra[T],m:measure_type[T,S]):
                              negligible_set?[T,S,m](X) => completion(S,m)(X)

    is_completion(S:sigma_algebra[T],m:measure_type[T,S])(A,B):bool
      = completion(S,m)(A) AND S(B) =>
        EXISTS (N1,N2:negligible[T,S,m]): A = difference(union(B,N1),N2)

    m_completions: LEMMA FORALL (S:sigma_algebra[T],m:measure_type[T,S],X,A,B):
                         completion(S,m)(X) AND S(A) AND S(B) AND
                         is_completion(S,m)(X,A) AND  is_completion(S,m)(X,B) =>
                         x_eq(m(A),m(B))

    choose_completion: LEMMA FORALL (S:sigma_algebra[T],m:measure_type[T,S],X):
                         completion(S,m)(X) => 
           is_completion(S,m)(X,choose({Y:(S) | EXISTS (N1,N2:negligible[T,S,m]):
                   X = difference(union(Y,N1),N2)}))

    completion(S:sigma_algebra[T],m:measure_type[T,S]):
                                              complete_measure[T,completion(S,m)]
      = lambda (X:(completion(S,m))):
          m(choose({Y:(S) | EXISTS (N1,N2:negligible[T,S,m]):
                   X = difference(union(Y,N1),N2)}))

    completion_measurable: LEMMA
      FORALL (S:sigma_algebra[T],m:measure_type[T,S],X:(S)):
             x_eq(completion(S,m)(X),m(X))

    completion_negligible: LEMMA
      FORALL (S:sigma_algebra[T],m:measure_type[T,S],N:negligible[T,S,m]):
             completion(S,m)(N) = (TRUE,0)

  END measure_completion_aux

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 24, column 42) for  measure_type[T, S]
      % generated from assumption generalized_measure_def.S_empty
  almost_measurable?_TCC1: OBLIGATION
    FORALL (S: sigma_algebra[T]): S(emptyset[T]);

  % Subtype TCC generated (at line 41, column 6) for
      % {X | almost_measurable?(S, m)(X)}
      % expected type  sigma_algebra[T]
  completion_TCC1: OBLIGATION
    FORALL (S: sigma_algebra[T], m: measure_type[T, S]):
      sigma_algebra?[T]({X | almost_measurable?(S, m)(X)});

  % Subtype TCC generated (at line 64, column 37) for
      % {Y: (S) |
      %    EXISTS (N1, N2: negligible[T, S, m]):
      %      X = difference(union(Y, N1), N2)}
      % expected type  p: (nonempty?[(S)])
  choose_completion_TCC1: OBLIGATION
    FORALL (S: sigma_algebra[T], m: measure_type[T, S], X: set[T]):
      completion(S, m)(X) IMPLIES
       nonempty?[(S)]
           ({Y: (S) |
               EXISTS (N1, N2: negligible[T, S, m]):
                 X = difference[T](union[T](Y, N1), N2)});

  % Subtype TCC generated (at line 70, column 17) for
      % {Y: (S) |
      %    EXISTS (N1, N2: negligible[T, S, m]):
      %      X = difference(union(Y, N1), N2)}
      % expected type  p: (nonempty?[(S)])
  completion_TCC2: OBLIGATION
    FORALL (S: sigma_algebra[T], m: measure_type[T, S],
            X: (completion(S, m))):
      nonempty?[(S)]
          ({Y: (S) |
              EXISTS (N1, N2: negligible[T, S, m]):
                X = difference[T](union[T](Y, N1), N2)});

  % Subtype TCC generated (at line 69, column 6) for
      % LAMBDA (X: (completion(S, m))):
      %   m(choose({Y: (S) |
      %               EXISTS (N1, N2: negligible[T, S, m]):
      %                 X = difference(union(Y, N1), N2)}))
      % expected type  complete_measure[T, completion(S, m)]
  completion_TCC3: OBLIGATION
    FORALL (S: sigma_algebra[T], m: measure_type[T, S]):
      complete_measure?[T, completion(S, m)]
          (LAMBDA (X: (completion(S, m))):
             m(choose[(S)]
                   ({Y: (S) |
                       EXISTS (N1, N2: negligible[T, S, m]):
                         X = difference[T](union[T](Y, N1), N2)})));

  % Subtype TCC generated (at line 75, column 32) for  X
      % expected type  (completion(S, m))
  completion_measurable_TCC1: OBLIGATION
    FORALL (S: sigma_algebra[T], m: measure_type[T, S], X: (S)):
      completion(S, m)(X);

  % Subtype TCC generated (at line 79, column 27) for  N
      % expected type  (completion(S, m))
  completion_negligible_TCC1: OBLIGATION
    FORALL (S: sigma_algebra[T], m: measure_type[T, S],
            N: negligible[T, S, m]):
      completion(S, m)(N);


body:
  %------------------------------------------------------------------------------
  % Completing a measure 
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % Note: not described in Berberian 
  %
  % Any measure can be "completed", by adding the negligible sets to the
  % sigma_algebra and then extending the measure for these extra sets.
  %
  % Details of the actual extension mechanisms are in measure_completion_aux.
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  measure_completion[T:TYPE,          (IMPORTING subset_algebra_def[T])
                     S:sigma_algebra, (IMPORTING measure_def[T,S])
                     m:measure_type]: THEORY

  BEGIN

    IMPORTING measure_completion_aux[T],
              measure_theory[T,S,m]

    X: VAR (S)
    N: VAR negligible[T,S,m]

    sigma_algebra_completion: sigma_algebra[T] = completion(S,m)

    generated_completion: LEMMA 
      generated_sigma_algebra(union(S,fullset[negligible[T,S,m]]))
        = sigma_algebra_completion

    completion: complete_measure[T,completion(S,m)] = completion(S,m)

    completion_measurable: LEMMA x_eq(completion(X),m(X))

    completion_negligible: LEMMA completion(N) = (TRUE,0)

  END measure_completion

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 34, column 14) for
      % complete_measure[T, completion(S, m)]
      % generated from assumption generalized_measure_def.S_empty
  completion_TCC1: OBLIGATION completion[T](S, m)(emptyset[T]);

  % Subtype TCC generated (at line 36, column 47) for  X
      % expected type  (completion(S, m))
  completion_measurable_TCC1: OBLIGATION
    FORALL (X: (S)): completion[T](S, m)(X);

  % Subtype TCC generated (at line 38, column 42) for  N
      % expected type  (completion(S, m))
  completion_negligible_TCC1: OBLIGATION
    FORALL (N: negligible[T, S, m]): completion[T](S, m)(N);


body:
  %-------------------------------------------------------------------------
  % Outer Measure Theory Definition file.
  %
  %     Author: David Lester, Manchester University
  %
  %     Version 1.0           20/08/07	Initial (DRL)
  %-------------------------------------------------------------------------

  outer_measure_def[T:TYPE]: THEORY

  BEGIN

    IMPORTING extended_nnreal@extended_nnreal,
              structures@fun_preds_partial[nat,set[T],reals.<=,subset?[T]],
              sets_aux@indexed_sets_aux[nat,T]

    f:   VAR [set[T]->extended_nnreal]
    X:   VAR [nat->set[T]]
    a,b: VAR set[T]

    om_empty?(f):bool             = f(emptyset[T]) = (TRUE,0)
    om_increasing?(f):bool        = FORALL a,b: subset?(a,b) => x_le(f(a),f(b))
    om_countably_subadditive?(f):bool
                                  = FORALL X: x_le(f(IUnion(X)), x_sum(f o X))

    outer_measure?(f):bool = om_empty?(f) AND
                             om_increasing?(f) AND
                             om_countably_subadditive?(f)

    zero_outer_measure(a):extended_nnreal = (TRUE,0)

    outer_measure: TYPE+ = (outer_measure?) CONTAINING zero_outer_measure

  END outer_measure_def

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 32, column 53) for  zero_outer_measure
      % expected type  outer_measure
  outer_measure_TCC1: OBLIGATION outer_measure?(zero_outer_measure);


body:
  %------------------------------------------------------------------------------
  % Properties of Outer Measures
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  outer_measure_props[T:TYPE,(IMPORTING outer_measure_def[T])
                      m:outer_measure]: THEORY

  BEGIN

    IMPORTING outer_measure_def[T],
              subset_algebra_def[T],
              orders@bounded_nats % proof only

    i:   VAR nat
    x,y: VAR set[T]
    A:   VAR sequence[set[T]]

    m_outer_empty:       LEMMA m(emptyset[T]) = (TRUE,0)
    m_outer_increasing:  LEMMA subset?(x,y) => x_le(m(x),m(y))
    m_outer_subadditive: LEMMA x_le(m(IUnion(A)),x_sum(m o A))

    outer_negligible?(x):bool = m(x) = (TRUE,0)

    outer_measurable?(x):bool                               % (Generalised) 2.2.2
      = FORALL y: x_eq(m(y), x_add(m(intersection(y,x)),
                                   m(intersection(y,complement(x)))))

    outer_negligible: TYPE+ = (outer_negligible?) CONTAINING emptyset[T]
    outer_measurable: TYPE+ = (outer_measurable?) CONTAINING emptyset[T]

                                                            % (Generalised) 2.2.3
    pairwise_subadditive:LEMMA x_le(m(y),x_add(m(intersection(y,x)),
                                               m(intersection(y,complement(x)))))

    outer_measurable_def:LEMMA
      outer_measurable?(x) <=>
      (FORALL y: x_le(x_add(m(intersection(y,x)),
                            m(intersection(y,complement(x)))),m(y)))

    outer_negligible_is_outer_measurable:
                           JUDGEMENT outer_negligible SUBTYPE_OF outer_measurable

    a,b:   VAR outer_measurable
    X:     VAR sequence[outer_measurable]
    S:     VAR setofsets[T]
                                                            % (Generalised) 2.2.4
    outer_measurable_complement:JUDGEMENT complement(a) HAS_TYPE outer_measurable
    outer_measurable_emptyset:  JUDGEMENT emptyset[T]   HAS_TYPE outer_measurable
    outer_measurable_fullset:   JUDGEMENT fullset[T]    HAS_TYPE outer_measurable
    outer_measurable_union:     JUDGEMENT union(a,b)    HAS_TYPE outer_measurable
    outer_measurable_intersection:
                            JUDGEMENT intersection(a,b) HAS_TYPE outer_measurable
    outer_measurable_difference:
                            JUDGEMENT difference(a,b)   HAS_TYPE outer_measurable

    outer_measurable_disjoint_union: LEMMA disjoint?(a,b) =>
                           x_eq(m(intersection(x,union(a,b))),
                                x_add(m(intersection(x,a)),m(intersection(x,b))))

    outer_measurable_IUnion: JUDGEMENT IUnion(X)        HAS_TYPE outer_measurable
    outer_measurable_IIntersection:
                             JUDGEMENT IIntersection(X) HAS_TYPE outer_measurable

    outer_measurable_Union: LEMMA is_countable(S) AND
                                  every(outer_measurable?,S) =>
                                  outer_measurable?(Union(S))

    outer_measurable_Intersection: LEMMA is_countable(S) AND
                                         every(outer_measurable?,S) =>
                                         outer_measurable?(Intersection(S))

    outer_measurable_disjoint_IUnion: LEMMA disjoint?(X) => % (Generalised) 2.2.5
               x_eq(m(intersection(x,IUnion(X))),
                    x_sum(lambda i: m(intersection(x,X(i)))))

    outer_measure_disjoint_IUnion: LEMMA disjoint?(X) =>   % (Generalised) 2.2.10
               x_eq(m(IUnion(X)),x_sum(m o X))

    outer_measurable_is_sigma_algebra: LEMMA                              % 7.1.5
                                        sigma_algebra?(fullset[outer_measurable])

    induced_sigma_algebra:sigma_algebra[T] = (outer_measurable?)

    IMPORTING measure_def[T,induced_sigma_algebra]

    induced_measure:complete_measure                                      % 7.1.5
      = restrict[set[T],(induced_sigma_algebra),extended_nnreal](m)

    induced_measure_rew: LEMMA induced_measure(a) = m(a)

    n,n1,n2: VAR outer_negligible

    outer_negligible_emptyset:  JUDGEMENT emptyset[T]   HAS_TYPE outer_negligible
    outer_negligible_union:     JUDGEMENT union(n1,n2)  HAS_TYPE outer_negligible

    outer_negligible_subset: LEMMA subset?(x,n) => outer_negligible?(x)

  END outer_measure_props

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 35, column 59) for  emptyset[T]
      % expected type  outer_negligible
  outer_negligible_TCC1: OBLIGATION outer_negligible?(emptyset[T]);

  % Subtype TCC generated (at line 36, column 59) for  emptyset[T]
      % expected type  outer_measurable
  outer_measurable_TCC1: OBLIGATION outer_measurable?(emptyset[T]);

  % Judgement subtype TCC generated (at line 48, column 35) for  x
      % expected type  outer_measurable
  outer_negligible_is_outer_measurable: OBLIGATION
    FORALL (x: outer_negligible): outer_measurable?(x);

  % Judgement subtype TCC generated (at line 54, column 40) for  complement(a)
      % expected type  outer_measurable
  outer_measurable_complement: OBLIGATION
    FORALL (a): outer_measurable?(complement[T](a));

  % Judgement subtype TCC generated (at line 55, column 40) for  emptyset[T]
      % expected type  outer_measurable
  outer_measurable_emptyset: OBLIGATION outer_measurable?(emptyset[T]);

  % Judgement subtype TCC generated (at line 56, column 40) for  fullset[T]
      % expected type  outer_measurable
  outer_measurable_fullset: OBLIGATION outer_measurable?(fullset[T]);

  % Judgement subtype TCC generated (at line 57, column 40) for  union(a, b)
      % expected type  outer_measurable
  outer_measurable_union: OBLIGATION
    FORALL (a, b): outer_measurable?(union[T](a, b));

  % Judgement subtype TCC generated (at line 59, column 36) for
      % intersection(a, b)
      % expected type  outer_measurable
  outer_measurable_intersection: OBLIGATION
    FORALL (a, b): outer_measurable?(intersection[T](a, b));

  % Judgement subtype TCC generated (at line 61, column 36) for
      % difference(a, b)
      % expected type  outer_measurable
  outer_measurable_difference: OBLIGATION
    FORALL (a, b): outer_measurable?(difference[T](a, b));

  % Judgement subtype TCC generated (at line 67, column 37) for  IUnion(X)
      % expected type  outer_measurable
  outer_measurable_IUnion: OBLIGATION
    FORALL (X): outer_measurable?(IUnion[nat, T](X));

  % Judgement subtype TCC generated (at line 69, column 37) for
      % IIntersection(X)
      % expected type  outer_measurable
  outer_measurable_IIntersection: OBLIGATION
    FORALL (X): outer_measurable?(IIntersection[nat, T](X));

  % Subtype TCC generated (at line 89, column 44) for  (outer_measurable?)
      % expected type  sigma_algebra[T]
  induced_sigma_algebra_TCC1: OBLIGATION
    sigma_algebra?[T]((outer_measurable?));

  % Subtype TCC generated (at line 94, column 6) for
      % restrict[set[T], (induced_sigma_algebra), extended_nnreal](m)
      % expected type  complete_measure[T, induced_sigma_algebra]
  induced_measure_TCC1: OBLIGATION
    complete_measure?[T, induced_sigma_algebra]
        (restrict[set[T], (induced_sigma_algebra), extended_nnreal](m));

  % Subtype TCC generated (at line 96, column 45) for  a
      % expected type  (induced_sigma_algebra)
  induced_measure_rew_TCC1: OBLIGATION
    FORALL (a: outer_measurable): induced_sigma_algebra(a);

  % Judgement subtype TCC generated (at line 100, column 40) for  emptyset[T]
      % expected type  outer_negligible
  outer_negligible_emptyset: OBLIGATION outer_negligible?(emptyset[T]);

  % Judgement subtype TCC generated (at line 101, column 40) for  union(n1, n2)
      % expected type  outer_negligible
  outer_negligible_union: OBLIGATION
    FORALL (n1, n2): outer_negligible?(union[T](n1, n2));


body:
  %-------------------------------------------------------------------------
  % Extension of a measure to and outer measure
  %
  %     Author: David Lester, Manchester University
  %
  %     Version 1.0           20/08/07	Initial (DRL)
  %     Version 1.1           29/07/09    Now suitable for interval measures
  %                                       (DRL)
  %-------------------------------------------------------------------------
  ast_def[T:TYPE,A:(nonempty?[set[T]])]: THEORY

  BEGIN

    ASSUMING IMPORTING subset_algebra_def[T]

      A_empty:        ASSUMPTION A(emptyset)
      A_fullset:      ASSUMPTION A(fullset)
      A_intersection: ASSUMPTION FORALL (a,b:(A)): A(intersection(a,b))
      A_difference:   ASSUMPTION FORALL (a,b:(A)):
                                 finite_disjoint_union?(A)(difference(a,b))

    ENDASSUMING

    IMPORTING generalized_measure_def[T,A],
              outer_measure_def[T],
              extended_nnreal@double_index[set[T]] % Proof Only

    mu: VAR measure_type
    z:  VAR extended_nnreal
    epsilon: VAR posreal
    X:  VAR set[T]
    Y:  VAR (A)
    I:  VAR sequence[(A)]
    a,b: VAR set[T]
    i,n:  VAR nat

    A_difference_union:  LEMMA A(a) AND finite_disjoint_union?(A)(b) =>
                               finite_disjoint_union?(A)(difference(a,b))

    measure_subadditive: LEMMA A(IUnion(I)) => x_le(mu(IUnion(I)), x_sum(mu o I))

    generalized_monotonicity: LEMMA 
      disjoint?(I)           AND
      subset?(IUnion(n,I),Y) AND
      (FORALL i: i >= n => empty?(I(i))) =>
      x_le(x_sum(mu o I),mu(Y))

    generalized_measure_monotone: LEMMA FORALL (a,b:(A),mu): subset?(a,b)  =>
                                                             x_le(mu(a),mu(b))

    ast(mu):outer_measure = lambda X:                                     % 7.1.3
      x_inf({z | EXISTS I: x_eq(x_sum(mu o I),z) AND subset?(X,IUnion(I))})

    outer_measure_eq: LEMMA x_eq(ast(mu)(Y),mu(Y))                        % 7.1.3

    outer_measure_def: LEMMA
      EXISTS I: subset?(X,IUnion(I)) AND
                x_le(x_sum(mu o I),x_add(ast(mu)(X),epsilon))

  END ast_def

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 24, column 12) for
      % generalized_measure_def[T, A]
      % generated from assumption generalized_measure_def.S_empty
  IMP_generalized_measure_def_TCC1: OBLIGATION A(emptyset[T]);

  % Subtype TCC generated (at line 51, column 26) for
      % LAMBDA X:
      %   x_inf({z |
      %            EXISTS I:
      %              x_eq(x_sum(mu o I), z) AND subset?(X, IUnion(I))})
      % expected type  outer_measure[T]
  ast_TCC1: OBLIGATION
    FORALL (mu: measure_type[T, A]):
      outer_measure?[T]
          (LAMBDA X:
             x_inf({z |
                      EXISTS I:
                        x_eq(x_sum(o[nat, (A), extended_nnreal](mu, I)), z)
                         AND subset?[T](X, IUnion[nat, T](I))}));


body:
  %------------------------------------------------------------------------------
  % Outer Measure
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  outer_measure[T:TYPE,        (IMPORTING subset_algebra_def[T])
                A:subset_algebra]: THEORY

  BEGIN

    IMPORTING subset_algebra[T,A],
              ast_def[T,A]

  END outer_measure

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 18, column 22) for  A
      % expected type  (nonempty?[set[T]])
  IMP_ast_def_TCC1: OBLIGATION nonempty?[set[T]](A);

  % Assuming TCC generated (at line 18, column 12) for  ast_def[T, A]
      % generated from assumption ast_def.A_empty
  IMP_ast_def_TCC2: OBLIGATION A(emptyset[T]);

  % Assuming TCC generated (at line 18, column 12) for  ast_def[T, A]
      % generated from assumption ast_def.A_fullset
  IMP_ast_def_TCC3: OBLIGATION A(fullset[T]);

  % Assuming TCC generated (at line 18, column 12) for  ast_def[T, A]
      % generated from assumption ast_def.A_intersection
  IMP_ast_def_TCC4: OBLIGATION FORALL (a, b: (A)): A(intersection[T](a, b));

  % Assuming TCC generated (at line 18, column 12) for  ast_def[T, A]
      % generated from assumption ast_def.A_difference
  IMP_ast_def_TCC5: OBLIGATION
    FORALL (a, b: (A)): finite_disjoint_union?[T](A)(difference[T](a, b));


body:
  %------------------------------------------------------------------------------
  % Hahn-Kolmogorov Theorem
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to SK Berberian "Fundamentals of Real Analysis",
  % Springer, 1991
  %
  % Extending a measure from an algebra to a sigma-algebra
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------

  hahn_kolmogorov[T:TYPE,           (IMPORTING subset_algebra_def[T])
                  A:subset_algebra, (IMPORTING measure_def[T,A])
                  mu: measure_type]: THEORY

  BEGIN

    IMPORTING outer_measure[T,A],
              outer_measure_props[T,ast(mu)]

    x: VAR (A)

    algebra_in_induced_sigma_algebra: LEMMA subset?(A,induced_sigma_algebra)

    IMPORTING measure_theory[T,induced_sigma_algebra,induced_measure]

    induced_measure_measure: LEMMA x_eq(induced_measure(x),mu(x))

  END hahn_kolmogorov

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 20, column 28) for  A
      % expected type  (nonempty?[set[T]])
  IMP_outer_measure_props_TCC1: OBLIGATION nonempty?[set[T]](A);

  % Subtype TCC generated (at line 27, column 51) for  induced_measure
      % expected type  measure_type[T, induced_sigma_algebra]
  IMP_measure_theory_TCC1: OBLIGATION
    measure?[T, induced_sigma_algebra](induced_measure[T, ast(mu)]);

  % Subtype TCC generated (at line 29, column 54) for  x
      % expected type  (induced_sigma_algebra)
  induced_measure_measure_TCC1: OBLIGATION
    FORALL (x: (A)): induced_sigma_algebra[T, ast(mu)](x);


body:
  %------------------------------------------------------------------------------
  % Composition of Borel Functions
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------
  composition_borel[(IMPORTING topology@topology_def)
                    T1:Type, S:topology[T1],
                    T2:Type, T:topology[T2],
                    T3:Type, U:topology[T3]]: THEORY

  BEGIN

    IMPORTING borel_functions[T1,S,T2,T],
              borel_functions[T2,T,T3,U],
              borel_functions[T1,S,T3,U]

    f: VAR [T2->T3]
    g: VAR [T1->T2]

    composition_borel: LEMMA borel_function?(f) AND borel_function?(g) =>
                             borel_function?(f o g)

    F: VAR borel_function[T2,T,T3,U]
    G: VAR borel_function[T1,S,T2,T]

    composition_is_borel: JUDGEMENT o(F,G) HAS_TYPE borel_function[T1,S,T3,U]

  END composition_borel

addendum:
  %%% ================ Addendum: generated declarations ================

  % Judgement subtype TCC generated (at line 31, column 34) for  F o G
      % expected type  borel_function[T1, S, T3, U]
  composition_is_borel: OBLIGATION
    FORALL (F, G): borel_function?[T1, S, T3, U](o[T1, T2, T3](F, G));


body:
  %------------------------------------------------------------------------------
  % Identity preserves Borel-ness
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            1/5/07   Initial Version
  %------------------------------------------------------------------------------
  identity_borel[T:TYPE, (IMPORTING topology@topology_def[T]) S:topology]: THEORY

  BEGIN

    IMPORTING borel_functions[T,S,T,S]

    id_borel   : LEMMA borel_function?(I[T])
    I_is_borel : JUDGEMENT I[T] HAS_TYPE borel_function

  END identity_borel

addendum:
  %%% ================ Addendum: generated declarations ================

  % Judgement subtype TCC generated (at line 18, column 25) for  I[T]
      % expected type  borel_function[T, S, T, S]
  I_is_borel: OBLIGATION borel_function?[T, S, T, S](I[T]);


body:
  %------------------------------------------------------------------------------
  % Metric Spaces
  %
  %     Author: David Lester, Manchester University
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            17/08/07  Initial Version
  %
  % Note that an alternate version of metric spaces is available in the analysis
  % library.  See
  %
  %    metric_spaces[T:TYPE+,d:[T,T->nnreal]]: THEORY
  %    BEGIN
  %
  %      ASSUMING IMPORTING metric_spaces_def[T,d]
  %          fullset_metric_space: ASSUMPTION metric_space?[T,d](fullset[T])
  %      ENDASSUMING
  %
  % This version does not use the topology library.
  %------------------------------------------------------------------------------

  top: THEORY

  BEGIN

    IMPORTING
  % Extra results
      countable_cross,   % the cross product of two countable sets is countable

  % Basic properties
      metric_def,        % Definition of metric
      metric_space_def,  % Basic properties of metric spaces
      metric_space,      % Deeper results
      submetric_def,     % metrics for sub-spaces
      metric_subspace,   % subspaces of metric spaces
      complete_product,  % products of complete metrics

  % Continuity in metric spaces
      metric_continuity, % Continuity expressed using metrics (epsilon/delta)
      composition_continuous,
                         % composition is continuous
      composition_uniform_continuity,
                         % composing uniform continuous functions

  % Convergence properties
      convergence_aux,   % Properties of convergence in metric spaces

  % real topology results
      real_topology,     % The topology of the reals
      heine_borel_scaf,  % Foundations for ...
      heine_borel,       % Heine-Borel
      euclidean,         % Topology of R^n (Vector[n])
      real_continuity,   % Continuity of functions [T->real]
  %%%%%%%%%%%%%% RWB %%%%%%%%%%%%% <<temporary>. %%%%%%%%%%%%%    
      continuity_link,   % Linking continuity with that in the analysis library
      continuity_subspace, % Continuity on subspaces
      test_cont          % A surprising, but correct result: 1/x is continuous 
                         % (provided that the domain is taken to be the metric space
                         % induced topology restricted to the nonzero reals.)

  END top


body:
  %------------------------------------------------------------------------------
  % Countable cross products
  %
  %     Author: David Lester, Manchester University
  %
  %     Version 1.0            17/08/07  Initial Version
  %------------------------------------------------------------------------------
  countable_cross[T1,T2:TYPE]: THEORY

  BEGIN


    IMPORTING sets_aux@countability,
              topology@cross_product[T1,T2]

    X: VAR set[T1]
    Y: VAR set[T2]

    is_countable_cross: LEMMA is_countable(X) AND is_countable(Y) =>
                              is_countable(cross_product(X,Y))

  END countable_cross


body:
  %------------------------------------------------------------------------------
  % Metric Spaces Basics
  %
  %     Author: David Lester, Manchester University
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            5/12/04  Initial Version DRL
  %------------------------------------------------------------------------------

  metric_space_def[T:TYPE, d:[T,T -> nnreal]]: THEORY

  BEGIN

    x,y:   VAR T
    r:     VAR posreal
    S,X,Y: VAR set[T]

    metric_zero?(S)     :bool = FORALL (x,y:(S)):   d(x,y)  = 0 <=> x = y
    metric_symmetric?(S):bool = FORALL (x,y:(S)):   d(x,y)  = d(y,x)
    metric_triangle?(S) :bool = FORALL (x,y,z:(S)): d(x,z) <= d(x,y) + d(y,z)

    metric_space?(S):bool
      = metric_zero?(S) AND metric_symmetric?(S) AND metric_triangle?(S)

    % The above defines a metric space, and is therefore all that _needs_
    % to be in this file. However, we will be interested in particular
    % specialized spaces, so we take this opportunity to define various
    % predicates on metric spaces that we will need later.

  % ball(x,r) is the open set, "centre" x, "radius" r.

    ball(x,r): set[T]     = {y | d(x,y) < r}

    metric_open?(S):   bool = FORALL x: (S(x) <=> EXISTS r: subset?(ball(x,r),S))

    metric_closed?(S): bool = metric_open?(complement(S))

    metric_induced_topology:setofsets[T] = {S | metric_open?(S)}

    metric_adherent?(x,S): bool = FORALL r: nonempty?(intersection(S,ball(x,r)))

    metric_limit?(x,S):    bool = metric_adherent?(x,S) AND NOT member(x,S)

    metric_closure(S): set[T]  = {x:T | metric_adherent?(x,S)}

    dense_in?(X,S): bool = subset?(X,S) AND subset?(S,metric_closure(X))

    IMPORTING sets_aux@countable_props

    separable?(S): bool
      = EXISTS X: subset?(X,S) AND is_countable(X) AND dense_in?(X,S)

    bounded?(S): bool   = EXISTS x,r: subset?(S,ball(x,r))

    epsilon_net?(S,X,r): bool
      = is_finite(X) AND subset?(X,S) AND
        subset?(S,Union(image[T,set[T]](lambda x: ball(x,r),X)))

    totally_bounded?(S): bool = FORALL r: EXISTS X: epsilon_net?(S,X,r)

    u:     VAR sequence[T]
    i,j,n: VAR nat

    metric_converges_to(u,x):bool
      = FORALL r: EXISTS n: FORALL i: i >= n => member(u(i),ball(x,r))

    metric_convergent?(S:set[T],u:sequence[(S)]):bool
      = EXISTS (x:(S)): metric_converges_to(u,x)

    metric_convergent?(u):bool = EXISTS x: metric_converges_to(u,x)

    cauchy?(u):bool = FORALL r: EXISTS n: FORALL i,j: i >= n AND j >= n
                                        => member(u(i),ball(u(j),r))

    metric_complete?(S): bool
      = FORALL (u:sequence[(S)]): cauchy?(u) => metric_convergent?(S,u)

    complete_metric_space?(S):bool = metric_space?(S) AND metric_complete?(S)

  % Alternative naming

    accumulation_point?: MACRO [T,set[T]->bool] = metric_limit?

  END metric_space_def


body:
  %------------------------------------------------------------------------------
  % Metric Spaces Definitions
  %
  %     Author: David Lester, Manchester University
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            17/08/07  Initial Version
  %------------------------------------------------------------------------------

  metric_def[T:TYPE]: THEORY

  BEGIN

    x,y,z: VAR T
    d:     VAR [T,T->nnreal]

    metric_zero?(d)     :bool = FORALL x,y:   d(x,y)  = 0 <=> x = y
    metric_symmetric?(d):bool = FORALL x,y:   d(x,y)  = d(y,x)
    metric_triangle?(d) :bool = FORALL x,y,z: d(x,z) <= d(x,y) + d(y,z)

    metric?(d):bool
      = metric_zero?(d) AND metric_symmetric?(d) AND metric_triangle?(d)

    discrete_metric(x,y):[nnreal] = IF x = y THEN 0 ELSE 1 ENDIF

    metric: TYPE+ = (metric?) CONTAINING discrete_metric

    discrete_metric_is_metric: JUDGEMENT discrete_metric HAS_TYPE metric

  END metric_def

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 28, column 39) for  discrete_metric
      % expected type  metric
  metric_TCC1: OBLIGATION metric?(discrete_metric);

  % Judgement subtype TCC generated (at line 30, column 39) for
      % discrete_metric
      % expected type  metric
  discrete_metric_is_metric: OBLIGATION metric?(discrete_metric);


body:
  %------------------------------------------------------------------------------
  % Metric space
  %
  %     Author: David Lester, Manchester University
  %
  %     Version 1.0             5/12/04  Initial Version
  %     Version 1.1            15/06/09  All Proofs discharged (DRL)
  %------------------------------------------------------------------------------

  metric_space[T:TYPE, (IMPORTING metric_def[T]) d:metric]: THEORY

  BEGIN

    IMPORTING metric_def[T],
              topology@topology_def[T],
              metric_space_def[T,d]

    S:     VAR set[T]
    x,y,z: VAR T
    r:     VAR posreal

    metric_open_set:set[T]   = emptyset[T]
    metric_closed_set:set[T] = complement(metric_open_set)

    metric_zero:      LEMMA d(x,y) = 0 <=> x = y
    metric_symmetric: LEMMA d(x,y)  = d(y,x)
    metric_triangle:  LEMMA d(x,z) <= d(x,y) + d(y,z)
    metric_is_0:      LEMMA d(x,x) = 0
    ball_centre:      LEMMA member(x,ball(x,r))
    metric_open_ball: LEMMA metric_open?(ball(x,r))

    metric_open:   TYPE+ = (metric_open?)   CONTAINING metric_open_set
    metric_closed: TYPE+ = (metric_closed?) CONTAINING metric_closed_set

    ball_is_metric_open: JUDGEMENT ball(x,r) HAS_TYPE metric_open

    metric_space_is_topology?:  JUDGEMENT metric_induced_topology
                                                       HAS_TYPE (topology?)
    metric_space_is_hausdorff?: JUDGEMENT metric_induced_topology
                                                       HAS_TYPE (hausdorff?)
    metric_space_is_topology:
                             JUDGEMENT metric_induced_topology HAS_TYPE topology
    metric_space_is_hausdorff:
                             JUDGEMENT metric_induced_topology HAS_TYPE hausdorff

    IMPORTING topology@topology[T,(metric_induced_topology)]

    metric_open_def:   LEMMA metric_open?(S)   <=> open?(S)
    metric_closed_def: LEMMA metric_closed?(S) <=> closed?(S)

    metric_open_is_open:     JUDGEMENT metric_open   SUBTYPE_OF open
    open_is_metric_open:     JUDGEMENT open          SUBTYPE_OF metric_open
    metric_closed_is_closed: JUDGEMENT metric_closed SUBTYPE_OF closed
    closed_is_metric_closed: JUDGEMENT closed        SUBTYPE_OF metric_closed

    metric_adherent_iff_adherent: LEMMA
                          metric_adherent?(x,S) <=> adherent_point?(x,S)

    metric_closure_is_Cl: LEMMA metric_closure(S) = Cl(S)

    IMPORTING topology@hausdorff_convergence[T,(metric_induced_topology)],
              sets_aux@countable_setofsets, % proof only
              sets_aux@countable_image,     % proof only
              countable_cross                     % proof only

    u,v: VAR sequence[T]

    metric_convergence_def: LEMMA convergence?(u,x) <=> metric_converges_to(u,x)

    weierstrass_bolzano?:bool
      = FORALL u: EXISTS v: subseq?(v,u) AND metric_convergent?(v)

    compact_is_weierstrass_bolzano: LEMMA                            % SKB 6.1.11
          compact?(fullset[T]) => weierstrass_bolzano?

    cauchy_subseq_is_totally_bounded: LEMMA                          % SKB 6.1.17
          (FORALL u: EXISTS v: cauchy?(v) AND subseq?(v,u)) =>
          totally_bounded?(fullset[T])

    totally_bounded_is_separable: LEMMA                              % SKB 6.1.19
          totally_bounded?(fullset[T]) => separable?(fullset[T])

    separable_has_countable_basis: LEMMA                             % SKB 6.1.21
          separable?(fullset[T]) => has_countable_basis?(metric_induced_topology)

    IMPORTING topology@lindelof,               % Proof Only
              sets_aux@nat_indexed_sets[T],      % Proof Only
              sets_aux@countable_indexed_sets[T] % Proof Only

    compact_iff_convergent_subseq: LEMMA                             % SKB 6.1.23
          compact?(fullset[T]) <=> weierstrass_bolzano?

    totally_bounded_iff_cauchy_subseq: LEMMA                         % SKB 6.1.24
          totally_bounded?(fullset[T]) <=>
          FORALL u: EXISTS v: cauchy?(v) AND subseq?(v,u)

    compact_is_complete_totally_bounded: LEMMA                       % SKB 6.1.26
          compact?(fullset[T]) <=>
          metric_complete?(fullset[T]) AND totally_bounded?(fullset[T])

    metric_complete: TYPE = (complete_metric_space?[T,d])

  END metric_space

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 32, column 53) for  metric_open_set
      % expected type  metric_open
  metric_open_TCC1: OBLIGATION metric_open?[T, d](metric_open_set);

  % Subtype TCC generated (at line 33, column 53) for  metric_closed_set
      % expected type  metric_closed
  metric_closed_TCC1: OBLIGATION metric_closed?[T, d](metric_closed_set);

  % Judgement subtype TCC generated (at line 35, column 33) for  ball(x, r)
      % expected type  metric_open
  ball_is_metric_open: OBLIGATION
    FORALL (r, x): metric_open?[T, d](ball[T, d](x, r));

  % Judgement subtype TCC generated (at line 37, column 40) for
      % metric_induced_topology
      % expected type  (topology?)
  metric_space_is_topology?: OBLIGATION
    topology?[T](metric_induced_topology[T, d]);

  % Judgement subtype TCC generated (at line 39, column 40) for
      % metric_induced_topology
      % expected type  (hausdorff?)
  metric_space_is_hausdorff?: OBLIGATION
    hausdorff?[T](metric_induced_topology[T, d]);

  % Judgement subtype TCC generated (at line 44, column 37) for
      % metric_induced_topology
      % expected type  hausdorff[T]
  metric_space_is_hausdorff: OBLIGATION
    hausdorff_space?[T](metric_induced_topology[T, d]);

  % Judgement subtype TCC generated (at line 51, column 37) for  x
      % expected type  open[T, (metric_induced_topology)]
  metric_open_is_open: OBLIGATION
    FORALL (x: metric_open): open?[T, (metric_induced_topology)](x);

  % Judgement subtype TCC generated (at line 52, column 37) for  x
      % expected type  metric_open
  open_is_metric_open: OBLIGATION FORALL (x: open): metric_open?[T, d](x);

  % Judgement subtype TCC generated (at line 53, column 37) for  x
      % expected type  closed[T, (metric_induced_topology)]
  metric_closed_is_closed: OBLIGATION
    FORALL (x: metric_closed): closed?[T, (metric_induced_topology)](x);

  % Judgement subtype TCC generated (at line 54, column 37) for  x
      % expected type  metric_closed
  closed_is_metric_closed: OBLIGATION
    FORALL (x: closed): metric_closed?[T, d](x);


body:
  %------------------------------------------------------------------------------
  % Metric Continuity
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Author: David Lester, Manchester University
  %
  %     Version 1.0            20/3/07  Initial Version
  %------------------------------------------------------------------------------

  metric_continuity[T1:TYPE, (IMPORTING metric_def[T1]) d1:metric[T1],
                    T2:TYPE, (IMPORTING metric_def[T2]) d2:metric[T2]]:THEORY

  BEGIN

    IMPORTING metric_space[T1,d1],
              metric_space[T2,d2],
              topology@topology_def[T1],
              topology@topology_def[T2],
              topology@topology[T1,metric_induced_topology[T1,d1]],
              topology@topology[T2,metric_induced_topology[T2,d2]],
              topology@hausdorff_convergence[T1,metric_induced_topology[T1,d1]],
              topology@hausdorff_convergence[T2,metric_induced_topology[T2,d2]],
              topology@continuity_def[T1,metric_induced_topology[T1,d1],
                                      T2,metric_induced_topology[T2,d2]],
              topology@continuity[T1,metric_induced_topology[T1,d1],
                                  T2,metric_induced_topology[T2,d2]]

    f:             VAR [T1->T2]
    x,x0:          VAR T1
    u:             VAR sequence[T1]
    epsilon,delta: VAR posreal

    metric_continuous_at?(f,x0):bool
       = FORALL epsilon: EXISTS delta: FORALL x:
             member(x,ball(x0,delta)) => member(f(x),ball(f(x0),epsilon))

    metric_continuous?(f):bool = FORALL x: metric_continuous_at?(f,x)

    metric_continuous_at_def: LEMMA 
       continuous_at?(f,x0) <=> metric_continuous_at?(f,x0)

    metric_continuous_def: LEMMA
       continuous?(f) <=> metric_continuous?(f)

    metric_continuity_limit: LEMMA
       convergence?(u,x) AND metric_continuous_at?(f,x) =>
       convergence?(f o u, f(x))

    metric_continuous: TYPE = (metric_continuous?)

    metric_continuous_is_continuous:
                              JUDGEMENT metric_continuous SUBTYPE_OF continuous

    continuous_is_metric_continuous:
                              JUDGEMENT continuous SUBTYPE_OF metric_continuous

    uniform_continuous?(f):bool =
       (FORALL epsilon: EXISTS delta: FORALL x,x0:
                    member(x,ball(x0,delta)) => member(f(x),ball(f(x0),epsilon)))

    uniform_continuous: LEMMA uniform_continuous?(f) => continuous?(f)

    uniform_continuous: TYPE = (uniform_continuous?)

    uniform_continuous_is_continuous:
           JUDGEMENT uniform_continuous SUBTYPE_OF continuous

    IMPORTING  finite_sets@finite_sets_minmax[posreal,<=] % proof only

    compact_uniform_continuous: LEMMA
       compact_subset?(metric_induced_topology[T1,d1],fullset[T1]) =>
                (continuous?(f) <=> uniform_continuous?(f))

  END metric_continuity

addendum:
  %%% ================ Addendum: generated declarations ================

  % Judgement subtype TCC generated (at line 54, column 38) for  x
      % expected type  continuous
                     %     [T1, metric_induced_topology[T1, d1], T2,
                     %      metric_induced_topology[T2, d2]]
  metric_continuous_is_continuous: OBLIGATION
    FORALL (x: metric_continuous):
      continuous?
          [T1, metric_induced_topology[T1, d1], T2,
           metric_induced_topology[T2, d2]]
          (x);

  % Judgement subtype TCC generated (at line 57, column 38) for  x
      % expected type  metric_continuous
  continuous_is_metric_continuous: OBLIGATION
    FORALL (x: continuous): metric_continuous?(x);

  % Judgement subtype TCC generated (at line 68, column 19) for  x
      % expected type  continuous
  uniform_continuous_is_continuous: OBLIGATION
    FORALL (x: uniform_continuous):
      continuous?
          [T1, metric_induced_topology[T1, d1], T2,
           metric_induced_topology[T2, d2]]
          (x);


body:
  %------------------------------------------------------------------------------
  % continuity on subspaces
  %
  %     Author: David Lester, Manchester University
  %
  %     Version 1.0            15/06/09  Initial Version
  %------------------------------------------------------------------------------
  continuity_subspace[(IMPORTING metric_def)
                      T1:TYPE,d1:metric[T1],
                      T2:TYPE,d2:metric[T2],
                      T3:TYPE FROM T1]: THEORY

  BEGIN

    IMPORTING
      metric_space[T1,d1],
      metric_space[T2,d2],
      topology@continuity_subspace[T1,metric_induced_topology[T1,d1],
                                   T2,metric_induced_topology[T2,d2],T3],
      topology@continuity_def[T3,induced_topology,
                              T2,metric_induced_topology[T2,d2]],
      metric_continuity[T3,(restrict[[T1,T1],[T3,T3],nnreal](d1)),T2,d2]

  END continuity_subspace

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 22, column 26) for
      % (restrict[[T1, T1], [T3, T3], nnreal](d1))
      % expected type  metric[T3]
  IMP_metric_continuity_TCC1: OBLIGATION
    metric?[T3]((restrict[[T1, T1], [T3, T3], nnreal](d1)));


body:
  %------------------------------------------------------------------------------
  % Metric Spaces
  %
  %     Author: David Lester, Manchester University, NIA, Universite Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            17/08/07  Initial Version
  %     Version 1.1            23/03/11  New intervals added for probability
  %------------------------------------------------------------------------------

  real_topology: THEORY

  BEGIN

    IMPORTING metric_space_def[real,(LAMBDA (x,y:real): abs(x-y))],
              metric_space[real,(LAMBDA (x,y:real): abs(x-y))],
              reals@bounded_reals,
              countable_cross[rat,posrat],    % Proof Only
              sets_aux@countable_types  % Proof only

    a,x,y: VAR real
    r:   VAR posreal
    q:   VAR rat
    pq:  VAR posrat
    X,A: VAR set[real]

    interval?(A):bool = FORALL (x,y:(A),z:real): x <= z AND z <= y => A(z)

    bounded?(A):bool
      = (empty?(A) OR
        (nonempty?(A) AND above_bounded[real](A) AND below_bounded[real](A)))

    unbounded?(A):bool = NOT bounded?(A)

    bounded_interval?(A):bool      = interval?(A) AND bounded?(A)
    unbounded_interval?(A):bool    = interval?(A) AND unbounded?(A)
    bounded_open_interval?(A):bool = bounded_interval?(A) and metric_open?(A)

    interval:           TYPE+ = (interval?)           CONTAINING emptyset[real]
    bounded_interval:   TYPE+ = (bounded_interval?)   CONTAINING emptyset[real]
    unbounded_interval: TYPE+ = (unbounded_interval?) CONTAINING fullset[real]
    bounded_open_interval:
                        TYPE+ = (bounded_open_interval?)CONTAINING emptyset[real]

    open_interval: TYPE+ = {X | EXISTS x,r: X = ball(x,r)}

    open_interval_is_bounded_open_interval:
              JUDGEMENT open_interval SUBTYPE_OF bounded_open_interval

    open_basis: LEMMA base?(metric_induced_topology)(fullset[open_interval])

    rational_open_interval: TYPE+ = {X | EXISTS q,pq: X = ball(q,pq)}

    rational_basis: LEMMA
                 base?(metric_induced_topology)(fullset[rational_open_interval])

    countable_rational_open_interval: LEMMA
        is_countable(fullset[rational_open_interval])

    metric_induced_topology_is_second_countable:
                   JUDGEMENT metric_induced_topology HAS_TYPE second_countable

    real_is_complete: JUDGEMENT fullset[real] HAS_TYPE metric_complete

    closed_ball(x:real,r:nnreal):closed = {y | abs(x-y) <= r}

    closed_interval: TYPE+ = {X | EXISTS (x:real,r:nnreal): X = closed_ball(x,r)}

    open(a:real,b:{x | a < x}):   open_interval   = ball((a+b)/2,(b-a)/2)
    closed(a:real,b:{x | a <= x}):closed_interval = closed_ball((a+b)/2,(b-a)/2)

    open_inf(a):open = {x | a < x}
    inf_open(a):open = {x | x < a}

    reals:open    = fullset[real]
    posreals:open = open_inf(0)
    negreals:open = inf_open(0)

    closed_inf(a):closed = {x | a <= x}
    inf_closed(a):closed = {x | x <= a}

    nnreals:closed = closed_inf(0)
    npreals:closed = inf_closed(0)

    left_semiclosed_interval:  TYPE+ = {X | EXISTS a: X = closed_inf(a)}
                                       CONTAINING closed_inf(0)
    right_semiclosed_interval: TYPE+ = {X | EXISTS a: X = inf_closed(a)}
                                       CONTAINING inf_closed(0)

    left_semiclosed_interval_is_interval:
                          JUDGEMENT left_semiclosed_interval  SUBTYPE_OF interval
    right_semiclosed_interval_is_interval:
                          JUDGEMENT right_semiclosed_interval SUBTYPE_OF interval

    left_semiclosed_interval_is_closed:
                          JUDGEMENT left_semiclosed_interval  SUBTYPE_OF closed
    right_semiclosed_interval_is_closed:
                          JUDGEMENT right_semiclosed_interval SUBTYPE_OF closed

  END real_topology

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 18, column 31) for
      % (LAMBDA (x, y: real): abs(x - y))
      % expected type  metric[real]
  IMP_metric_space_TCC1: OBLIGATION
    metric?[real]((LAMBDA (x, y: real): abs(x - y)));

  % Subtype TCC generated (at line 41, column 63) for  emptyset[real]
      % expected type  interval
  interval_TCC1: OBLIGATION interval?(emptyset[real]);

  % Subtype TCC generated (at line 42, column 63) for  emptyset[real]
      % expected type  bounded_interval
  bounded_interval_TCC1: OBLIGATION bounded_interval?(emptyset[real]);

  % Subtype TCC generated (at line 43, column 63) for  fullset[real]
      % expected type  unbounded_interval
  unbounded_interval_TCC1: OBLIGATION unbounded_interval?(fullset[real]);

  % Subtype TCC generated (at line 45, column 65) for  emptyset[real]
      % expected type  bounded_open_interval
  bounded_open_interval_TCC1: OBLIGATION
    bounded_open_interval?(emptyset[real]);

  % Existence TCC generated (at line 47, column 2) for
      % open_interval: TYPE+ = {X | EXISTS x, r: X = ball(x, r)}
  open_interval_TCC1: OBLIGATION
    EXISTS (x1:
              {X |
                       EXISTS x, r:
                         X =
                          ball[real, (LAMBDA (x, y: real): abs(x - y))]
                              (x, r)}):
      TRUE;

  % Judgement subtype TCC generated (at line 50, column 22) for  x
      % expected type  bounded_open_interval
  open_interval_is_bounded_open_interval: OBLIGATION
    FORALL (x: open_interval): bounded_open_interval?(x);

  % Existence TCC generated (at line 54, column 2) for
      % rational_open_interval: TYPE+ = {X | EXISTS q, pq: X = ball(q, pq)}
  rational_open_interval_TCC1: OBLIGATION
    EXISTS (x:
              {X |
                       EXISTS q, pq:
                         X =
                          ball[real, (LAMBDA (x, y: real): abs(x - y))]
                              (q, pq)}):
      TRUE;

  % Judgement subtype TCC generated (at line 63, column 27) for
      % metric_induced_topology
      % expected type  second_countable[real]
  metric_induced_topology_is_second_countable: OBLIGATION
    second_countable?[real]
        (metric_induced_topology[real, (LAMBDA (x, y: real): abs(x - y))]);

  % Judgement subtype TCC generated (at line 65, column 30) for  fullset[real]
      % expected type  metric_complete
                     %     [real, (LAMBDA (x, y: real): abs(x - y))]
  real_is_complete: OBLIGATION
    complete_metric_space?[real, (LAMBDA (x, y: real): abs(x - y))]
        (fullset[real]);

  % Subtype TCC generated (at line 67, column 40) for  {y | abs(x - y) <= r}
      % expected type  closed[real, (metric_induced_topology)]
  closed_ball_TCC1: OBLIGATION
    FORALL (x: real, r: nnreal):
      closed?[real, (metric_induced_topology)]({y | abs(x - y) <= r});

  % Existence TCC generated (at line 69, column 2) for
      % closed_interval: TYPE+ =
      %       {X | EXISTS (x: real, r: nnreal): X = closed_ball(x, r)}
  closed_interval_TCC1: OBLIGATION
    EXISTS (x1: {X | EXISTS (x: real, r: nnreal): X = closed_ball(x, r)}):
      TRUE;

  % Subtype TCC generated (at line 71, column 63) for  (b - a) / 2
      % expected type  posreal
  open_TCC1: OBLIGATION
    FORALL (a: real, b: {x | a < x}): (b - a) / 2 >= 0 AND (b - a) / 2 > 0;

  % Subtype TCC generated (at line 71, column 50) for
      % ball((a + b) / 2, (b - a) / 2)
      % expected type  open_interval
  open_TCC2: OBLIGATION
    FORALL (a: real, b: {x | a < x}):
      EXISTS x, r:
        ball[real, (LAMBDA (x, y: real): abs(x - y))]
            ((a + b) / 2, (b - a) / 2)
         = ball[real, (LAMBDA (x, y: real): abs(x - y))](x, r);

  % Subtype TCC generated (at line 72, column 70) for  (b - a) / 2
      % expected type  nnreal
  closed_TCC1: OBLIGATION FORALL (a: real, b: {x | a <= x}): (b - a) / 2 >= 0;

  % Subtype TCC generated (at line 72, column 50) for
      % closed_ball((a + b) / 2, (b - a) / 2)
      % expected type  closed_interval
  closed_TCC2: OBLIGATION
    FORALL (a: real, b: {x | a <= x}):
      EXISTS (x: real, r: nnreal):
        closed_ball((a + b) / 2, (b - a) / 2) = closed_ball(x, r);

  % Subtype TCC generated (at line 74, column 21) for  {x | a < x}
      % expected type  open[real, (metric_induced_topology)]
  open_inf_TCC1: OBLIGATION
    FORALL (a: real): open?[real, (metric_induced_topology)]({x | a < x});

  % Subtype TCC generated (at line 75, column 21) for  {x | x < a}
      % expected type  open[real, (metric_induced_topology)]
  inf_open_TCC1: OBLIGATION
    FORALL (a: real): open?[real, (metric_induced_topology)]({x | x < a});

  % Subtype TCC generated (at line 81, column 25) for  {x | a <= x}
      % expected type  closed[real, (metric_induced_topology)]
  closed_inf_TCC1: OBLIGATION
    FORALL (a: real): closed?[real, (metric_induced_topology)]({x | a <= x});

  % Subtype TCC generated (at line 82, column 25) for  {x | x <= a}
      % expected type  closed[real, (metric_induced_topology)]
  inf_closed_TCC1: OBLIGATION
    FORALL (a: real): closed?[real, (metric_induced_topology)]({x | x <= a});

  % Subtype TCC generated (at line 88, column 48) for  closed_inf(0)
      % expected type  left_semiclosed_interval
  left_semiclosed_interval_TCC1: OBLIGATION
    EXISTS a: closed_inf(0) = closed_inf(a);

  % Subtype TCC generated (at line 90, column 48) for  inf_closed(0)
      % expected type  right_semiclosed_interval
  right_semiclosed_interval_TCC1: OBLIGATION
    EXISTS a: inf_closed(0) = inf_closed(a);

  % Judgement subtype TCC generated (at line 93, column 34) for  x
      % expected type  interval
  left_semiclosed_interval_is_interval: OBLIGATION
    FORALL (x: left_semiclosed_interval): interval?(x);

  % Judgement subtype TCC generated (at line 95, column 34) for  x
      % expected type  interval
  right_semiclosed_interval_is_interval: OBLIGATION
    FORALL (x: right_semiclosed_interval): interval?(x);

  % Judgement subtype TCC generated (at line 98, column 34) for  x
      % expected type  closed[real, (metric_induced_topology)]
  left_semiclosed_interval_is_closed: OBLIGATION
    FORALL (x: left_semiclosed_interval):
      closed?[real, (metric_induced_topology)](x);

  % Judgement subtype TCC generated (at line 100, column 34) for  x
      % expected type  closed[real, (metric_induced_topology)]
  right_semiclosed_interval_is_closed: OBLIGATION
    FORALL (x: right_semiclosed_interval):
      closed?[real, (metric_induced_topology)](x);


body:
  %
  % Although this doesn't look right (1/x is continuous?), it is correct,
  % provided that the domain is taken to be the metric induced topology
  % restricted to the nonzero reals.
  %
  % This is a test that continuity_subspace captures the desired property.
  % (And it does!)

  test_cont: THEORY

  BEGIN

    IMPORTING real_topology,
              continuity_subspace[real,(LAMBDA (x,y:real): abs(x-y)),
                                  real,(LAMBDA (x,y:real): abs(x-y)),nzreal]

    recip_continuous: LEMMA metric_continuous?(lambda (x:nzreal): 1/x)

  END test_cont

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 14, column 38) for
      % (LAMBDA (x, y: real): abs(x - y))
      % expected type  metric[real]
  IMP_continuity_subspace_TCC1: OBLIGATION
    metric?[real]((LAMBDA (x, y: real): abs(x - y)));

  % Subtype TCC generated (at line 22, column 26) for
      % (restrict[[real, real], [nzreal, nzreal], nnreal]
      %      ((LAMBDA (x, y: real): abs(x - y))))
      % expected type  metric[nzreal]
  recip_continuous_TCC1: OBLIGATION
    metric?[nzreal]
        ((restrict[[real, real], [nzreal, nzreal], nnreal]
              ((LAMBDA (x, y: real): abs(x - y)))));


body:
  %------------------------------------------------------------------------------
  % Linking metric continuity to that in analysis, for T from real.
  %
  %     Author: David Lester, Manchester University
  %
  %     Version 1.0            15/06/09  Initial Version
  %------------------------------------------------------------------------------
  continuity_link[T: TYPE FROM real]: THEORY

  BEGIN

    IMPORTING analysis@continuous_functions[T],
              metric_space_def[real,(LAMBDA (x,y:real): abs(x-y))],
              metric_space[real,(LAMBDA (x,y:real): abs(x-y))],
              topology@continuity_subspace[real,metric_induced_topology,
                                           real,metric_induced_topology,T],
              metric_continuity[T,(lambda (x,y:T): abs(x-y)),
                                real,(LAMBDA (x,y:real): abs(x-y))]

    f: VAR [T->real]
    x: VAR T


     continuous_iff_continuous_at?: LEMMA
       continuous?[T](f,x) <=>
  %RWB     continuous_at?[T,induced_topology,real,metric_induced_topology](f,x)
       continuous_at?[T, metric_induced_topology[T, (LAMBDA (x, y: T): abs(x - y))],
          real,
          metric_induced_topology
              [real, (LAMBDA (x, y: real): abs(x - y))]](f,x)

     continuous_iff_continuous?:    LEMMA
       continuous?[T](f)   <=>
   %RWB    continuous?[T,induced_topology,real,metric_induced_topology](f)
      continuous?[T, metric_induced_topology[T, (LAMBDA (x, y: T): abs(x - y))],
          real, metric_induced_topology
              [real, (LAMBDA (x, y: real): abs(x - y))]](f)

  END continuity_link

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 14, column 31) for
      % (LAMBDA (x, y: real): abs(x - y))
      % expected type  metric[real]
  IMP_metric_space_TCC1: OBLIGATION
    metric?[real]((LAMBDA (x, y: real): abs(x - y)));

  % Subtype TCC generated (at line 17, column 33) for
      % (LAMBDA (x, y: T): abs(x - y))
      % expected type  metric[T]
  IMP_metric_continuity_TCC1: OBLIGATION
    metric?[T]((LAMBDA (x, y: T): abs(x - y)));


body:
  %------------------------------------------------------------------------------
  % Continuous functions [T->real]
  %
  %     Author: David Lester, Manchester University
  %
  %     Version 1.0            15/09/08  Initial Version
  %------------------------------------------------------------------------------

  real_continuity[T:TYPE,(IMPORTING metric_def[T]) d:metric]: THEORY

  BEGIN

    IMPORTING
      metric_continuity[T,d,real,(lambda (x,y:real): abs(x-y))],
      topology@constant_continuity[T,metric_induced_topology[T,d],
                                   real,metric_induced_topology[real,
                                              (lambda (x,y:real) :abs(x-y))]],
      reals@real_fun_ops_aux[T],
      power@real_expt,
      power@log,
      power@real_fun_power[T]

    g,g1,g2: VAR metric_continuous
    n: VAR nat
    u: VAR sequence[metric_continuous]
    c: VAR real
    a: VAR posreal
    x: VAR T
    h: VAR {g | FORALL x: g(x) >= 0}

  %;
  %  ^(g,a): MACRO [T->real] = real_fun_power.^(g,a);

    sum_continuous:       JUDGEMENT +(g1,g2)     HAS_TYPE metric_continuous
    opp_continuous:       JUDGEMENT -(g)         HAS_TYPE metric_continuous
    diff_continuous:      JUDGEMENT -(g1,g2)     HAS_TYPE metric_continuous
    scal_continuous:      JUDGEMENT *(c,g)       HAS_TYPE metric_continuous
    abs_continuous:       JUDGEMENT abs(g)       HAS_TYPE metric_continuous
    expt_real_continuous: JUDGEMENT ^(h,a)       HAS_TYPE metric_continuous
    expt_nat_continuous:  JUDGEMENT expt(g,n)    HAS_TYPE metric_continuous
    sq_continuous:        JUDGEMENT sq(g)        HAS_TYPE metric_continuous
    min_continuous:       JUDGEMENT min(g1,g2)   HAS_TYPE metric_continuous
    max_continuous:       JUDGEMENT max(g1,g2)   HAS_TYPE metric_continuous
    minimum_continuous:   JUDGEMENT minimum(u,n) HAS_TYPE metric_continuous
    maximum_continuous:   JUDGEMENT maximum(u,n) HAS_TYPE metric_continuous
    plus_continuous:      JUDGEMENT plus(g)      HAS_TYPE metric_continuous
    minus_continuous:     JUDGEMENT minus(g)     HAS_TYPE metric_continuous
    prod_continuous:      JUDGEMENT *(g1,g2)     HAS_TYPE metric_continuous

  END real_continuity

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 14, column 32) for
      % (LAMBDA (x, y: real): abs(x - y))
      % expected type  metric[real]
  IMP_metric_continuity_TCC1: OBLIGATION
    metric?[real]((LAMBDA (x, y: real): abs(x - y)));

  % Judgement subtype TCC generated (at line 34, column 34) for  g1 + g2
      % expected type  metric_continuous
                     %     [T, d, real, (LAMBDA (x, y: real): abs(x - y))]
  sum_continuous: OBLIGATION
    FORALL (g1, g2):
      metric_continuous?[T, d, real, (LAMBDA (x, y: real): abs(x - y))]
          ((+[T])(g1, g2));

  % Judgement subtype TCC generated (at line 35, column 34) for  -g
      % expected type  metric_continuous
                     %     [T, d, real, (LAMBDA (x, y: real): abs(x - y))]
  opp_continuous: OBLIGATION
    FORALL (g):
      metric_continuous?[T, d, real, (LAMBDA (x, y: real): abs(x - y))](-g);

  % Judgement subtype TCC generated (at line 36, column 34) for  g1 - g2
      % expected type  metric_continuous
                     %     [T, d, real, (LAMBDA (x, y: real): abs(x - y))]
  diff_continuous: OBLIGATION
    FORALL (g1, g2):
      metric_continuous?[T, d, real, (LAMBDA (x, y: real): abs(x - y))]
          ((-[T])(g1, g2));

  % Judgement subtype TCC generated (at line 37, column 34) for  c * g
      % expected type  metric_continuous
                     %     [T, d, real, (LAMBDA (x, y: real): abs(x - y))]
  scal_continuous: OBLIGATION
    FORALL (c, g):
      metric_continuous?[T, d, real, (LAMBDA (x, y: real): abs(x - y))]
          (*[T](c, g));

  % Judgement subtype TCC generated (at line 38, column 34) for  abs(g)
      % expected type  metric_continuous
                     %     [T, d, real, (LAMBDA (x, y: real): abs(x - y))]
  abs_continuous: OBLIGATION
    FORALL (g):
      metric_continuous?[T, d, real, (LAMBDA (x, y: real): abs(x - y))]
          (abs[T](g));

  % Subtype TCC generated (at line 39, column 36) for  h
      % expected type  [T -> nnreal]
  expt_real_continuous_TCC1: OBLIGATION FORALL (h, x1: T): h(x1) >= 0;

  % Judgement subtype TCC generated (at line 39, column 34) for  h ^ a
      % expected type  metric_continuous
                     %     [T, d, real, (LAMBDA (x, y: real): abs(x - y))]
  expt_real_continuous: OBLIGATION
    FORALL (a, h):
      metric_continuous?[T, d, real, (LAMBDA (x, y: real): abs(x - y))]
          (^[T](h, a));

  % Judgement subtype TCC generated (at line 40, column 34) for  expt(g, n)
      % expected type  metric_continuous
                     %     [T, d, real, (LAMBDA (x, y: real): abs(x - y))]
  expt_nat_continuous: OBLIGATION
    FORALL (g, n):
      metric_continuous?[T, d, real, (LAMBDA (x, y: real): abs(x - y))]
          (expt[T](g, n));

  % Judgement subtype TCC generated (at line 41, column 34) for  sq(g)
      % expected type  metric_continuous
                     %     [T, d, real, (LAMBDA (x, y: real): abs(x - y))]
  sq_continuous: OBLIGATION
    FORALL (g):
      metric_continuous?[T, d, real, (LAMBDA (x, y: real): abs(x - y))]
          (sq[T](g));

  % Judgement subtype TCC generated (at line 42, column 34) for  min(g1, g2)
      % expected type  metric_continuous
                     %     [T, d, real, (LAMBDA (x, y: real): abs(x - y))]
  min_continuous: OBLIGATION
    FORALL (g1, g2):
      metric_continuous?[T, d, real, (LAMBDA (x, y: real): abs(x - y))]
          (min[T](g1, g2));

  % Judgement subtype TCC generated (at line 43, column 34) for  max(g1, g2)
      % expected type  metric_continuous
                     %     [T, d, real, (LAMBDA (x, y: real): abs(x - y))]
  max_continuous: OBLIGATION
    FORALL (g1, g2):
      metric_continuous?[T, d, real, (LAMBDA (x, y: real): abs(x - y))]
          (max[T](g1, g2));

  % Judgement subtype TCC generated (at line 44, column 34) for  minimum(u, n)
      % expected type  metric_continuous
                     %     [T, d, real, (LAMBDA (x, y: real): abs(x - y))]
  minimum_continuous: OBLIGATION
    FORALL (n, u):
      metric_continuous?[T, d, real, (LAMBDA (x, y: real): abs(x - y))]
          (minimum[T](u, n));

  % Judgement subtype TCC generated (at line 45, column 34) for  maximum(u, n)
      % expected type  metric_continuous
                     %     [T, d, real, (LAMBDA (x, y: real): abs(x - y))]
  maximum_continuous: OBLIGATION
    FORALL (n, u):
      metric_continuous?[T, d, real, (LAMBDA (x, y: real): abs(x - y))]
          (maximum[T](u, n));

  % Judgement subtype TCC generated (at line 46, column 34) for  plus(g)
      % expected type  metric_continuous
                     %     [T, d, real, (LAMBDA (x, y: real): abs(x - y))]
  plus_continuous: OBLIGATION
    FORALL (g):
      metric_continuous?[T, d, real, (LAMBDA (x, y: real): abs(x - y))]
          (plus[T](g));

  % Judgement subtype TCC generated (at line 47, column 34) for  minus(g)
      % expected type  metric_continuous
                     %     [T, d, real, (LAMBDA (x, y: real): abs(x - y))]
  minus_continuous: OBLIGATION
    FORALL (g):
      metric_continuous?[T, d, real, (LAMBDA (x, y: real): abs(x - y))]
          (minus[T](g));

  % Judgement subtype TCC generated (at line 48, column 34) for  g1 * g2
      % expected type  metric_continuous
                     %     [T, d, real, (LAMBDA (x, y: real): abs(x - y))]
  prod_continuous: OBLIGATION
    FORALL (g1, g2):
      metric_continuous?[T, d, real, (LAMBDA (x, y: real): abs(x - y))]
          (*[T](g1, g2));


body:
  %------------------------------------------------------------------------------
  % Product of Complete Metric Spaces
  %
  %     Author: David Lester, Manchester University
  %
  %     Version 1.0            20/12/07  Initial Version
  %------------------------------------------------------------------------------

  complete_product[T0,T1:TYPE, (IMPORTING metric_def)
                   d0:metric[T0],d1:metric[T1]]: THEORY

  BEGIN

    z0,z1: VAR [T0,T1]

    IMPORTING reals@sqrt,
              metric_space_def[T0,d0],
              metric_space_def[T1,d1],
              metric_space_def,
              metric_def

    d2: MACRO metric[[T0,T1]] =
         (LAMBDA (z0,z1): sqrt(sq(d0(z0`1,z1`1))+sq(d1(z0`2,z1`2))))

    complete_d2: LEMMA metric_complete?(fullset[T0]) AND
                       metric_complete?(fullset[T1]) =>
                       metric_complete?[[T0,T1],d2](fullset[[T0,T1]])

  END complete_product

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 23, column 8) for
      % (LAMBDA (z0, z1): sqrt(sq(d0(z0`1, z1`1)) + sq(d1(z0`2, z1`2))))
      % expected type  metric[[T0, T1]]
  d2_TCC1: OBLIGATION
    metric?[[T0, T1]]
        ((LAMBDA (z0, z1): sqrt(sq(d0(z0`1, z1`1)) + sq(d1(z0`2, z1`2)))));


body:
  %------------------------------------------------------------------------------
  % Metric Spaces for Vector[n]
  %
  %     Author: David Lester, Manchester University
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            17/08/07  Initial Version
  %------------------------------------------------------------------------------
  euclidean[n:posnat]: THEORY

  BEGIN

    IMPORTING vectors@vectors[n],
              reals@sigma[below[n]],
              reals@sqrt,
              reals@bounded_reals,
              metric_def[Vector],
              metric_space_def

    X:     VAR set[Vector]
    x,y,z: VAR Vector
    i:     VAR below[n]
    r:     VAR posreal

    sigma_nnreal_eq_0: LEMMA FORALL (f:[below[n]->nnreal]):
            sigma(0,n-1,f) = 0 <=> (FORALL i: f(i) = 0)

    d1:metric   = LAMBDA x,y: sigma(0,n-1,(LAMBDA i: abs(x(i)-y(i))))

    d2:metric   = LAMBDA x,y: sqrt(sigma(0,n-1,(LAMBDA i: sq(x(i)-y(i)))))

    dinf:metric = LAMBDA x,y: max({z:nnreal | EXISTS i: abs(x(i)-y(i)) = z})

    euclidean_d1:   LEMMA metric_space?[Vector,d1](fullset[Vector])

    euclidean_d2:   LEMMA metric_space?[Vector,d2](fullset[Vector])

    euclidean_dinf: LEMMA metric_space?[Vector,dinf](fullset[Vector])

  % We now show that R^n has a countable basis.

    Qn : TYPE+ = [Index->rat] CONTAINING zero

    Qn_is_Vector: JUDGEMENT Qn SUBTYPE_OF Vector

    q:     VAR Qn
    pq:    VAR posrat

    IMPORTING metric_space[Vector,d2],
              countable_cross,         % Proof Only
              sets_aux@countable_types % Proof only

    Qn_countable: LEMMA is_countable(fullset[Qn])

    balls: TYPE+ = {X | EXISTS x,r: X = ball(x,r)} CONTAINING
                                                       ball[Vector,d2](zero,1)

    rational_balls: TYPE+ = {X | EXISTS q,pq: X = ball[Vector,d2](q,pq)}
                                     CONTAINING ball[Vector,d2](zero,1)

    ball_basis: LEMMA base?(metric_induced_topology[Vector,d2])(fullset[balls])


  % WAS:  Qn_dense: LEMMA dense_in?(fullset[Qn],fullset[Vector])

    Qn_dense: LEMMA dense_in?({x | EXISTS q: x=q},fullset[Vector])

    Qn_basis: LEMMA
               base?(metric_induced_topology[Vector,d2])(fullset[rational_balls])

    countable_rational_balls: LEMMA is_countable(fullset[rational_balls])

    euclidean_topology_is_second_countable:
          JUDGEMENT metric_induced_topology[Vector,d2] HAS_TYPE second_countable

    IMPORTING complete_product, % Proof only
              real_topology,    % Proof only
              vectors@vectors,  % Proof only
              reals@sigma       % Proof only

    euclidean_topology_is_complete:
          JUDGEMENT fullset[Vector[n]] HAS_TYPE metric_complete[Vector[n],d2]

  END euclidean

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 28, column 18) for  n - 1
      % expected type  T_high[below(n)]
  sigma_nnreal_eq_0_TCC1: OBLIGATION
    n - 1 >= 0 AND n - 1 < n OR (EXISTS (j: below(n)): n - 1 <= j);

  % Subtype TCC generated (at line 30, column 16) for
      % LAMBDA x, y: sigma(0, n - 1, (LAMBDA i: abs(x(i) - y(i))))
      % expected type  metric[Vector]
  d1_TCC1: OBLIGATION
    metric?[Vector]
        (LAMBDA x, y:
           sigma[below(n)](0, n - 1, (LAMBDA i: abs(x(i) - y(i)))));

  % Subtype TCC generated (at line 32, column 16) for
      % LAMBDA x, y: sqrt(sigma(0, n - 1, (LAMBDA i: sq(x(i) - y(i)))))
      % expected type  metric[Vector]
  d2_TCC1: OBLIGATION
    metric?[Vector]
        (LAMBDA x, y:
           sqrt(sigma[below(n)](0, n - 1, (LAMBDA i: sq(x(i) - y(i))))));

  % Subtype TCC generated (at line 34, column 32) for
      % {z: nnreal | EXISTS i: abs(x(i) - y(i)) = z}
      % expected type  max_set[nnreal]
  dinf_TCC1: OBLIGATION
    FORALL (x, y):
      nonempty?[nnreal]({z: nnreal | EXISTS i: abs(x(i) - y(i)) = z}) AND
       above_bounded[nnreal]({z: nnreal | EXISTS i: abs(x(i) - y(i)) = z})
        AND
        in_set[nnreal]
            (sup[nnreal]({z: nnreal | EXISTS i: abs(x(i) - y(i)) = z}),
             {z: nnreal | EXISTS i: abs(x(i) - y(i)) = z});

  % Subtype TCC generated (at line 34, column 16) for
      % LAMBDA x, y: max({z: nnreal | EXISTS i: abs(x(i) - y(i)) = z})
      % expected type  metric[Vector]
  dinf_TCC2: OBLIGATION
    metric?[Vector]
        (LAMBDA x, y:
           max[nnreal]({z: nnreal | EXISTS i: abs(x(i) - y(i)) = z}));

  % Subtype TCC generated (at line 44, column 39) for  zero
      % expected type  Qn
  Qn_TCC1: OBLIGATION FORALL (x1: Index[n]): rational_pred(zero[n](x1));

  % Subtype TCC generated (at line 58, column 53) for
      % ball[Vector, d2](zero, 1)
      % expected type  balls
  balls_TCC1: OBLIGATION
    EXISTS x, r: ball[Vector[n], d2](zero[n], 1) = ball[Vector, d2](x, r);

  % Subtype TCC generated (at line 61, column 46) for
      % ball[Vector, d2](zero, 1)
      % expected type  rational_balls
  rational_balls_TCC1: OBLIGATION
    EXISTS q, pq:
      ball[Vector[n], d2](zero[n], 1) = ball[Vector[n], d2](q, pq);

  % Subtype TCC generated (at line 63, column 26) for
      % metric_induced_topology[Vector, d2]
      % expected type  topology[Vector]
  ball_basis_TCC1: OBLIGATION
    topology?[Vector](metric_induced_topology[Vector[n], d2]);

  % Judgement subtype TCC generated (at line 76, column 18) for
      % metric_induced_topology[Vector, d2]
      % expected type  second_countable[Vector]
  euclidean_topology_is_second_countable: OBLIGATION
    second_countable?[Vector[n]](metric_induced_topology[Vector[n], d2]);

  % Judgement subtype TCC generated (at line 84, column 18) for
      % fullset[Vector[n]]
      % expected type  metric_complete[Vector, d2]
  euclidean_topology_is_complete: OBLIGATION
    complete_metric_space?[Vector[n], d2](fullset[Vector[n]]);


body:
  %------------------------------------------------------------------------------
  % Heine-Borel for the real topology
  %
  %     Author: David Lester, Manchester University
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            17/08/07  Initial Version
  %
  % Notes: The statement of the theorem is capable of considerable
  %        generalization. I just need a result for the reals now.
  %        I suspect that the generalized proof is probably easier too.
  %
  %        It isn't (easier)! The result is in metric_space, lemma
  %
  %          compact_is_complete_totally_bounded
  %------------------------------------------------------------------------------
  heine_borel_scaf: THEORY

  BEGIN

    IMPORTING real_topology,
              reals@bounded_reals[real]

    a,b,x: VAR real
    U,C:   VAR setofsets[real]

    heine_borel_aux: THEOREM
      a <= b AND every(open?,C) AND
      open_cover?(C,{x| a <= x AND x <= b},metric_induced_topology) =>
      EXISTS U: subset?(U,C) AND is_finite(U) AND
                 subset?({x| a <= x AND x <= b},Union(U))

  END heine_borel_scaf


body:
  %------------------------------------------------------------------------------
  % Heine-Borel for the real topology
  %
  %     Author: David Lester, Manchester University
  %
  % The proof follows WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            17/08/07  Initial Version
  %------------------------------------------------------------------------------

  heine_borel: THEORY

  BEGIN

    IMPORTING heine_borel_scaf

    a,b,x: VAR real

    real_heine_borel: THEOREM a <= b => compact?({x | a <= x AND x <= b})

  END heine_borel


body:
  %------------------------------------------------------------------------------
  % Metric Convergence Properties
  %
  %     Author: David Lester, Manchester University
  %
  %     Version 1.0            17/08/07  Initial Version
  %------------------------------------------------------------------------------
  convergence_aux: THEORY

  BEGIN
              
    IMPORTING metric_space_def[real,(LAMBDA (x,y:real): abs(x-y))],
              metric_space[real,(LAMBDA (x,y:real): abs(x-y))],
              reals@bounded_reals[real],
              reals@real_fun_ops_aux[nat],
              reals@real_fun_preds[nat]

    u,v: VAR sequence[real]
    x,y: VAR real
    n,i: VAR nat
    r:   VAR posreal
    nnc: VAR nnreal
    ua:  VAR (real_fun_preds.bounded_above?)
    ub:  VAR (real_fun_preds.bounded_below?)

  %  bounded_above?(u):bool = bounded_above?(image[nat,real](u,fullset[nat]))
  %  bounded_below?(u):bool = bounded_below?(image[nat,real](u,fullset[nat]))
    bounded_seq?(u)  :bool = bounded?(image[nat,real](u,fullset[nat]))

    bounded_seq_def: LEMMA bounded_seq?(u) <=>
                           (bounded_above?(u) AND bounded_below?(u))

    upper_bound?(u):[real->bool] = upper_bound?(image[nat,real](u,fullset[nat]))
    lower_bound?(u):[real->bool] = lower_bound?(image[nat,real](u,fullset[nat]))

    lub(ua):real = lub(image[nat,real](ua,fullset[nat]))
    glb(ub):real = glb(image[nat,real](ub,fullset[nat]))

  % following should be in real_topology, but is it even needed?
  %  cauchy_convergent: LEMMA cauchy?(u) <=> metric_convergent?(u)

    converges_upto?(u,x):bool = convergence?(u,x) AND increasing?(u)

    convergent_upto?(u):bool = EXISTS x: converges_upto?(u,x)

    converges_upto_bounded_above: LEMMA converges_upto?(u,x) =>
                                        bounded_above?(u)

    converges_upto_le: LEMMA converges_upto?(u,x) => (FORALL n: u(n) <= x)

    converges_upto_def: LEMMA
        converges_upto?(u,x) <=>
        increasing?(u) AND
        (FORALL n: u(n) <= x) AND
        (FORALL r: EXISTS n: FORALL i: i >= n => x-u(i) < r)

    converges_upto_is_lub: LEMMA 
        converges_upto?(u,x) <=>
            (bounded_above?(u) AND increasing?(u) AND
             least_upper_bound?(x,image[nat,real](u,fullset[nat])))

    bounded_above_is_convergent:
      LEMMA bounded_above?(u) AND increasing?(u) => convergent_upto?(u)

    converges_upto_add:  LEMMA converges_upto?(u,x) AND converges_upto?(v,y)
                               => converges_upto?(u+v,x+y)

    converges_upto_scal: LEMMA converges_upto?(u,x) =>
                               converges_upto?(nnc*u,nnc*x)

    converges_downto?(u,x):bool = convergence?(u,x) AND decreasing?(u)

    convergent_downto?(u):bool = EXISTS x: converges_downto?(u,x)

    converges_downto_bounded_below: LEMMA converges_downto?(u,x) =>
                                          bounded_below?(u)

    converges_downto_ge: LEMMA converges_downto?(u,x) => FORALL n: x<=u(n)

    converges_downto_def: LEMMA
        converges_downto?(u,x) <=>
        decreasing?(u) AND
        (FORALL n: x <= u(n)) AND
        (FORALL r: EXISTS n: FORALL i: i >= n => u(i)-x < r)

    converges_downto_is_glb: LEMMA 
        converges_downto?(u,x) <=>
            (bounded_below?(u) AND decreasing?(u) AND
             greatest_lower_bound?(x,image[nat,real](u,fullset[nat])))

    bounded_below_is_convergent:
      LEMMA bounded_below?(u) AND decreasing?(u) => convergent_downto?(u)

    converges_downto_add: LEMMA converges_downto?(u,x) AND converges_downto?(v,y)
                                => converges_downto?(u+v,x+y)

    converges_downto_scal:LEMMA converges_downto?(u,x) =>
                                converges_downto?(nnc*u,nnc*x)

    monotonic_converges?(u,x):bool
      = convergence?(u,x) AND (increasing?(u) OR decreasing?(u))

    monotonic_convergent?(u):bool = EXISTS x: monotonic_converges?(u,x)

  END convergence_aux

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 13, column 31) for
      % (LAMBDA (x, y: real): abs(x - y))
      % expected type  metric[real]
  IMP_metric_space_TCC1: OBLIGATION
    metric?[real]((LAMBDA (x, y: real): abs(x - y)));

  % Subtype TCC generated (at line 33, column 46) for
      % image[nat, real](u, fullset[nat])
      % expected type  (nonempty?[real])
  upper_bound?_TCC1: OBLIGATION
    FORALL (u: sequence[real]):
      nonempty?[real](image[nat, real](u, fullset[nat]));

  % Subtype TCC generated (at line 36, column 21) for
      % image[nat, real](ua, fullset[nat])
      % expected type  SA: (bounded_above?)
  lub_TCC1: OBLIGATION
    FORALL (ua: (real_fun_preds[nat].bounded_above?)):
      nonempty?[real](image[nat, real](ua, fullset[nat])) AND
       bounded_above?(image[nat, real](ua, fullset[nat]));

  % Subtype TCC generated (at line 37, column 21) for
      % image[nat, real](ub, fullset[nat])
      % expected type  SB: (bounded_below?)
  glb_TCC1: OBLIGATION
    FORALL (ub: (real_fun_preds[nat].bounded_below?)):
      nonempty?[real](image[nat, real](ub, fullset[nat])) AND
       bounded_below?(image[nat, real](ub, fullset[nat]));


body:
  %------------------------------------------------------------------------------
  % Composition of uniform continuous functions
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            20/3/07  Initial Version
  %------------------------------------------------------------------------------

  composition_uniform_continuity[
                     T1:Type,(IMPORTING metric_def[T1]) d1:metric[T1],
                     T2:Type,(IMPORTING metric_def[T2]) d2:metric[T2],
                     T3:Type,(IMPORTING metric_def[T3]) d3:metric[T3]]: THEORY

  BEGIN

    IMPORTING metric_continuity[T1,d1,T2,d2],
              metric_continuity[T2,d2,T3,d3],
              metric_continuity[T1,d1,T3,d3]


    f: VAR uniform_continuous[T2,d2,T3,d3]
    g: VAR uniform_continuous[T1,d1,T2,d2]

    composition_uniform_continuity:
        JUDGEMENT o(f,g) HAS_TYPE uniform_continuous[T1,d1,T3,d3]

  END composition_uniform_continuity

addendum:
  %%% ================ Addendum: generated declarations ================

  % Judgement subtype TCC generated (at line 28, column 16) for  f o g
      % expected type  uniform_continuous[T1, d1, T3, d3]
  composition_uniform_continuity: OBLIGATION
    FORALL (f, g): uniform_continuous?[T1, d1, T3, d3](o[T1, T2, T3](f, g));


body:
  %------------------------------------------------------------------------------
  % composition of metric continuous functions
  %
  %     Author: David Lester, Manchester University
  %
  %     Version 1.0            17/08/07  Initial Version
  %------------------------------------------------------------------------------
  composition_continuous[T1:TYPE, (IMPORTING metric_def[T1]) d1:metric[T1],
                         T2:TYPE, (IMPORTING metric_def[T2]) d2:metric[T2],
                         T3:TYPE, (IMPORTING metric_def[T3]) d3:metric[T3]]
  		                                                      : THEORY

  BEGIN

    IMPORTING metric_space[T1,d1],
              metric_space[T2,d2],
              metric_space[T3,d3],
              metric_continuity[T1,d1,T2,d2],
              metric_continuity[T2,d2,T3,d3],
              metric_continuity[T1,d1,T3,d3]

    f: VAR [T2->T3]
    g: VAR [T1->T2]
   
    composition_continuous: LEMMA metric_continuous?(g) AND
                                  metric_continuous?(f) =>
                                  metric_continuous?(f o g)



  END composition_continuous


body:
  %------------------------------------------------------------------------------
  % Subspaces of metric spaces
  %
  %     Author: David Lester, Manchester University
  %
  %     Version 1.0            17/08/07  Initial Version
  %------------------------------------------------------------------------------
  metric_subspace[T:TYPE, S: TYPE FROM T,
                  (IMPORTING metric_def[T]) d:metric]: THEORY

  BEGIN

    IMPORTING metric_def[T],
              topology@topology_def[T],
              metric_space_def[T,d],
              metric_space_def[S,(restrict[[T,T],[S,S],nnreal](d))],
              metric_space[T,d],
              metric_space[S,(restrict[[T,T],[S,S],nnreal](d))],
              topology@hausdorff_convergence[T,metric_induced_topology[T,d]]

    complete_subspace: LEMMA                                      % RKB 6.1.29(2)
        metric_complete?[T,d](fullset[T]) AND metric_closed?[T,d](fullset[S]) =>
           metric_complete?[S,(restrict[[T,T],[S,S],nnreal](d))](fullset[S])

  END metric_subspace

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 18, column 28) for
      % (restrict[[T, T], [S, S], nnreal](d))
      % expected type  metric[S]
  IMP_metric_space_TCC1: OBLIGATION
    metric?[S]((restrict[[T, T], [S, S], nnreal](d)));


body:
  %------------------------------------------------------------------------------
  % (sub-) Metric Spaces
  %
  %     Author: David Lester, Manchester University
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            17/08/07  Initial Version
  %------------------------------------------------------------------------------

  submetric_def[T1:TYPE, T2:TYPE FROM T1]: THEORY

  BEGIN

    IMPORTING metric_def[T1],
              metric_def[T2]

    d: VAR metric[T1]

    submetric_is_metric?: LEMMA metric?[T2](restrict[[T1,T1],[T2,T2],nnreal](d))

    submetric_is_metric: JUDGEMENT
      restrict[[T1,T1],[T2,T2],nnreal](d) HAS_TYPE metric[T2]

  END submetric_def

addendum:
  %%% ================ Addendum: generated declarations ================

  % Judgement subtype TCC generated (at line 24, column 4) for
      % restrict[[T1, T1], [T2, T2], nnreal](d)
      % expected type  metric[T2]
  submetric_is_metric: OBLIGATION
    FORALL (d): metric?[T2](restrict[[T1, T1], [T2, T2], nnreal](d));


body:
  top: THEORY
  %-------------------------------------------------------------------------
  % Numbers library  
  %
  %     Authors:   Rick Butler       NASA Langley
  %                Anthony Narkawicz NASA Langley
  %                Alfons Geser      HTWK Leipzig, Germany
  %-------------------------------------------------------------------------
  BEGIN

     IMPORTING 
  	     prime_factorization,   % factorization into primes
  	     unique_factorization,  % factorization is unique
  	     product_perm_lems,
  	     infinite_primes,       % set of primes has infinite cardinality
               sqrt_two,              % sqrt(2) irrational
               eq_mod,
  	     primes_sum_squares,    % every prime p with mod(p,4)=1 is a sum of two squares
  	     chinese_remainder,
  	     fermats_little_theorem % every prime p satisfies mod(a^p,p) = a for all a < p

  END top


body:
  eq_mod: THEORY
  %-------------------------------------------------------------------------------


  %-------------------------------------------------------------------------------
  BEGIN

      p: VAR nat
      a,b,c,d: VAR int
      j,k: VAR int

      IMPORTING ints@primes

      eq_mod(p)(a,b): bool = (EXISTS k: a = k*p + b)

      eq_mod_equiv: LEMMA equivalence?(eq_mod(p))

      eq_mod_mult : LEMMA eq_mod(p)(a,b) AND
                          eq_mod(p)(c,d) 
                         IMPLIES
                             eq_mod(p)(a*c,b*d)

      eq_mod_rem  : LEMMA p > 0 IMPLIES eq_mod(p)(j, rem(p)(j))


      IMPORTING ints@gcd   

      gcd_is_1: LEMMA prime?(p) AND NOT divides(p,a) IMPLIES
                      gcd(a,p) = 1

      Euclids_30: LEMMA prime?(p) AND divides(p,a*b) IMPLIES
                        divides(p,a) OR divides(p,b)

      eq_mod_cancel: LEMMA prime?(p) AND
                           NOT divides(p, c)
                      IMPLIES
                           eq_mod(p)(a*c,b*c) IMPLIES
                           eq_mod(p)(a,b)


  END eq_mod

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 29, column 26) for  p
      % expected type  {jj: int | a = 0 => jj /= 0}
  gcd_is_1_TCC1: OBLIGATION
    FORALL (a: int, p: nat):
      NOT divides(p, a) AND prime?(p) IMPLIES a = 0 => p /= 0;


body:
  fermats_little_theorem: THEORY
  %------------------------------------------------------------------------------
  %   Fermat's Little Theorem
  %
  %   Anthony Narkawicz
  %   December 2012
  %------------------------------------------------------------------------------
  BEGIN

      IMPORTING ints@mod_lems, ints@primes, eq_mod,
                reals@factorial, reals@binomial_identities,
  	      reals@polynomials

      n,m,p,l: VAR nat
      a,b: VAR nat
      k: VAR int
      np: VAR posnat

      prime_divides_choose: LEMMA
        prime?(p) AND np < p IMPLIES
        divides(p,C(p,np))


      Fermats_Little: THEOREM prime?(p) AND a<p %just for nats
                              IMPLIES 
                                 eq_mod(p)(a^p,a)

      fermats_little_theorem: THEOREM prime?(p) %just for nats
                              IMPLIES 
                                 eq_mod(p)(k^p,k)


  END fermats_little_theorem

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 21, column 20) for  np
      % expected type  {i: nat | i <= p}
  prime_divides_choose_TCC1: OBLIGATION
    FORALL (np: posnat, p: nat): np < p AND prime?(p) IMPLIES np <= p;

  % Subtype TCC generated (at line 26, column 43) for  p
      % expected type  {i: int | a /= 0 OR i >= 0}
  Fermats_Little_TCC1: OBLIGATION
    FORALL (a, p: nat): a < p AND prime?(p) IMPLIES a /= 0 OR p >= 0;

  % Subtype TCC generated (at line 30, column 43) for  p
      % expected type  {i: int | k /= 0 OR i >= 0}
  fermats_little_theorem_TCC1: OBLIGATION
    FORALL (k: int, p: nat): prime?(p) IMPLIES k /= 0 OR p >= 0;


body:
  chinese_remainder: THEORY

  % The Chinese Remainder Theorem
  % Author(s): Anthony Narkawicz
  %
  % Date: March 2012

  BEGIN

  IMPORTING ints@gcd,reals@product_nat

  N: VAR posnat

  m1,m2: VAR posnat

  a1,a2: VAR nat


  chinese_remainder_base : LEMMA
    rel_prime(m1,m2) IMPLIES
    EXISTS (k:below(m1*m2)): mod(a1,m1)=mod(k,m1) AND mod(a2,m2) = mod(k,m2)

  mseq : VAR [nat->posnat]
  aseq : VAR [nat->nat]

  chinese_remainder : LEMMA
    (FORALL (i,j:below(N)): i/=j IMPLIES rel_prime(mseq(i),mseq(j)))
    IMPLIES
    (EXISTS (k:nat): FORALL (i:below(N)): mod(aseq(i),mseq(i)) = mod(k,mseq(i)))







  END chinese_remainder

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 20, column 15) for  m2
      % expected type  {jj: int | m1 = 0 => jj /= 0}
  chinese_remainder_base_TCC1: OBLIGATION
    FORALL (m1, m2: posnat): m1 = 0 => m2 /= 0;

  % Subtype TCC generated (at line 27, column 57) for  mseq(j)
      % expected type  {jj: int | mseq(i) = 0 => jj /= 0}
  chinese_remainder_TCC1: OBLIGATION
    FORALL (N: posnat, mseq: [nat -> posnat], i, j: below(N)):
      i /= j IMPLIES mseq(i) = 0 => mseq(j) /= 0;


body:
  product_perm_lems: THEORY
  %------------------------------------------------------------------------------
  %
  % NOTE: At some point this theory should be integrated with
  %       structures@permutation
  %
  %------------------------------------------------------------------------------

  BEGIN


     IMPORTING reals@product_fseq_posnat
     IMPORTING structures@permutations_fseq[posnat,<=]
     IMPORTING structures@sort_fseq[posnat,<=]
    
     fs,fs1,fs2: VAR fseq[posnat]

     swap(fs)(i,j: nat): fseq[posnat] =
                        (# length := length(fs),
                           seq := (LAMBDA (ii: nat):
                                      IF ii >= length(fs) THEN default
                                      ELSIF    ii = i THEN fs(j)
                                      ELSIF ii = j THEN fs(i)
                                      ELSE fs(ii)
                                      ENDIF)
                        #)

     i,j,k,l: VAR nat
     swap_len: LEMMA length(swap(fs)(i,j)) = length(fs)

     swap_eq_arg: LEMMA swap(fs)(i,i) = fs

     swap_symm: LEMMA swap(fs)(i,j) = swap(fs)(j,i)


     prod_swap_prep: LEMMA i <= j AND (j < k OR i > l) IMPLIES
                         product(k, l, swap(fs)(i, j)`seq)
                         = product(k,l, fs`seq)

     prod_swap_prep2: LEMMA i <= j AND (i < k AND j > l) IMPLIES
                            product(k, l, swap(fs)(i, j)`seq) = product(k,l, fs`seq)

     product_swap: LEMMA FORALL (i,j: below(length(fs))):
                                product(swap(fs)(i,j)) = product(fs)


     swap_is_permutation: LEMMA FORALL (i,j: below(length(fs))):
                                     permutation?(swap(fs)(i,j),fs)


     product_permutation: LEMMA permutation?(fs1,fs2) IMPLIES
                                product(fs1) = product(fs2)


     non_decreasing?(fs): bool = 
         (FORALL (i,j: below(length(fs))): i < j IMPLIES seq(fs)(i) <= seq(fs)(j))


     length_sort: LEMMA (sort(fs))`length = fs`length



     product_sort: LEMMA product(sort(fs)) = product(fs)


  END product_perm_lems

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 20, column 33) for
      % (LAMBDA (ii: nat):
      %    IF ii >= length(fs) THEN default
      %    ELSIF ii = i THEN fs`seq(j)
      %    ELSIF ii = j THEN fs`seq(i)
      %    ELSE fs`seq(ii)
      %    ENDIF)
      % expected type  barray[posnat](length(fs))
  swap_TCC1: OBLIGATION
    FORALL (fs: fseq[posnat], i, j: nat):
      FORALL (i_1: nat):
        i_1 >= length(fs) IMPLIES
         IF i_1 >= length(fs) THEN default[posnat]
         ELSIF i_1 = i THEN fs`seq(j)
         ELSIF i_1 = j THEN fs`seq(i)
         ELSE fs`seq(i_1)
         ENDIF
          = default[posnat];

  % Subtype TCC generated (at line 37, column 34) for  l
      % expected type  T_high[nat]
  prod_swap_prep_TCC1: OBLIGATION
    FORALL (i, j1, k, l: nat):
      (j1 < k OR i > l) AND i <= j1 IMPLIES
       l >= 0 OR (EXISTS (j: nat): l <= j);

  % Subtype TCC generated (at line 41, column 37) for  l
      % expected type  T_high[nat]
  prod_swap_prep2_TCC1: OBLIGATION
    FORALL (i, j1, k, l: nat):
      j1 > l AND i < k AND i <= j1 IMPLIES
       l >= 0 OR (EXISTS (j: nat): l <= j);


body:
  prime_factorization: THEORY
  BEGIN

     IMPORTING ints@primes

     m: VAR posnat
     N,n: VAR nat


     IMPORTING reals@product_fseq_posnat

     fs: VAR fseq

     prime_factorization: LEMMA FORALL m:
                                  (EXISTS fs: m = product(fs) AND
                                     (FORALL (i: below(length(fs))): 
                                             prime?(seq(fs)(i))))



     list_of_primes?(fs): bool = (FORALL (i: below(length(fs))): prime?(seq(fs)(i)))

     IMPORTING product_perm_lems

     ordered_list_of_primes?(fs): bool = list_of_primes?(fs) AND
                                         non_decreasing?(fs)
     
     prime_factors: LEMMA FORALL (m: posnat): 
                              (EXISTS fs: m = product_fseq_posnat.product(fs) AND
                                 ordered_list_of_primes?(fs))

  END prime_factorization


body:
  primes_sum_squares: THEORY

  %------------------------------------------------------------------------------
  % Every Prime p with mod(p,4)=1 is a Sum of Two Squares
  % Author: Anthony Narkawicz
  % Date:   March 2012
  %-------------------------------------------------------------------------------
  BEGIN

     IMPORTING ints@primes,ints@gcd, prime_factorization

      % The lemmas below are part of Euler's proof of this result
      % As noted below, the proof using this method is not completed.
      % Instead, Zagier's simpler proof of the result is finally used below

      n,m,i,j,a,b: VAR nat
      pa,pb: VAR posnat
      ai,bi: VAR int
      p: VAR (prime?)

      sum_of_two_squares?(n) : bool = (EXISTS (a,b): n=a^2+b^2)

      sots_int?(n) : bool = (EXISTS (ai,bi): n = ai^2+bi^2)

      sots_int_def: LEMMA sots_int?(n) IMPLIES sum_of_two_squares?(n)

      prime_sum_of_two_squares?(n): bool = prime?(n) AND sum_of_two_squares?(n)

      ns,ms,is,js,bs: VAR (sum_of_two_squares?)

      ps,qs	  : VAR (prime_sum_of_two_squares?)

      Brahmagupta_Fibonacci: LEMMA sum_of_two_squares?(ns*ms)

      prime_divides: LEMMA divides(p,ai*bi) IMPLIES (divides(p,ai) OR divides(p,bi))

      sots_div_prime_closed: LEMMA divides(ps,ns) IMPLIES sum_of_two_squares?(ns/ps)

      sots_div_quot_factor: LEMMA sum_of_two_squares?(ns) AND divides(m,ns) AND (NOT sum_of_two_squares?(m)) IMPLIES
      			  	(EXISTS (b): divides(b,ns/m) AND (NOT sum_of_two_squares?(b)))

      rel_prime_sos_factor: LEMMA rel_prime(pa,pb) AND divides(n,pa^2+pb^2) IMPLIES sum_of_two_squares?(n)

      % This ends the work on Euler's proof
      % As it turns out, Zagier's "one line proof" works much better in this context,
      % and it is given below.

      fermat_prime_sos_set(p)(x,y,z:nat): bool = x^2 + 4*y*z = p

      fermat_prime_sos_finite_set: LEMMA 
        finite_sets[[nat,nat,nat]].is_finite(fermat_prime_sos_set(p))

      involution_odd_has_fixedpoint: LEMMA
        FORALL (N:posnat,invol:[below(N)->below(N)]):
        odd?(N) AND (FORALL (i:below(N)): invol(invol(i)) = i) IMPLIES
        EXISTS (i:below(N)): invol(i) = i

      involution_one_fixedpoint_odd: LEMMA
        FORALL (N:posnat,invol:[below(N)->below(N)]):
        (FORALL (i:below(N)): invol(invol(i)) = i) AND
        (EXISTS (j:below(N)): FORALL (i:below(N)): invol(i)=i IFF i=j)
        IMPLIES
        odd?(N)

     involution_fermat_set_one_fp_invol: LEMMA
        LET invol:[[nat,nat,nat]->[nat,nat,nat]] = 
           (LAMBDA (x,y,z:nat): IF x<y-z THEN (x+2*z,z,y-x-z)
  	 	 	   ELSIF y-z <= x AND x <= 2*y THEN (2*y-x,y,x-y+z)
  			   ELSE (x-2*y,x-y+z,y) ENDIF)
        IN (FORALL (x,y,z:nat): fermat_prime_sos_set(p)(x,y,z) IMPLIES
          invol(invol(x,y,z)) = (x,y,z) AND
  	fermat_prime_sos_set(p)(invol(x,y,z)))

      invol_fermat(p)(xyz: (fermat_prime_sos_set(p))): (fermat_prime_sos_set(p)) =
        LET (x,y,z) = xyz IN
        IF x<y-z THEN (x+2*z,z,y-x-z)
  	 	 	   ELSIF y-z <= x AND x <= 2*y THEN (2*y-x,y,x-y+z)
  			   ELSE (x-2*y,x-y+z,y) ENDIF

      k : VAR posnat

      invol_fermat_one_fp: LEMMA p = 4*k+1 IMPLIES
        FORALL (xyz:(fermat_prime_sos_set(p))):
          invol_fermat(p)(xyz) = xyz IFF xyz = (1,1,k)

      fermat_prime_mod_4: LEMMA mod(p,4) = 1 IMPLIES
        sum_of_two_squares?(p)

  END primes_sum_squares

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 21, column 55) for  2
      % expected type  {i: int | a /= 0 OR i >= 0}
  sum_of_two_squares?_TCC1: OBLIGATION FORALL (a: nat): a /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 23, column 50) for  2
      % expected type  {i: int | ai /= 0 OR i >= 0}
  sots_int?_TCC1: OBLIGATION FORALL (ai: int): ai /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 37, column 79) for  ps
      % expected type  nznum
  sots_div_prime_closed_TCC1: OBLIGATION
    FORALL (ns: (sum_of_two_squares?), ps: (prime_sum_of_two_squares?)):
      divides(ps, ns) IMPLIES ps /= 0;

  % Subtype TCC generated (at line 37, column 76) for  ns / ps
      % expected type  nat
  sots_div_prime_closed_TCC2: OBLIGATION
    FORALL (ns: (sum_of_two_squares?), ps: (prime_sum_of_two_squares?)):
      divides(ps, ns) IMPLIES integer_pred(ns / ps) AND ns / ps >= 0;

  % Subtype TCC generated (at line 40, column 36) for  m
      % expected type  nznum
  sots_div_quot_factor_TCC1: OBLIGATION
    FORALL (m: nat, ns: (sum_of_two_squares?)):
      (NOT sum_of_two_squares?(m)) AND
       divides(m, ns) AND sum_of_two_squares?(ns)
       IMPLIES m /= 0;

  % Subtype TCC generated (at line 40, column 33) for  ns / m
      % expected type  int
  sots_div_quot_factor_TCC2: OBLIGATION
    FORALL (m: nat, ns: (sum_of_two_squares?)):
      (NOT sum_of_two_squares?(m)) AND
       divides(m, ns) AND sum_of_two_squares?(ns)
       IMPLIES integer_pred(ns / m);

  % Subtype TCC generated (at line 42, column 45) for  pb
      % expected type  {jj: int | pa = 0 => jj /= 0}
  rel_prime_sos_factor_TCC1: OBLIGATION
    FORALL (pa, pb: posnat): pa = 0 => pb /= 0;

  % Subtype TCC generated (at line 42, column 66) for  2
      % expected type  {i: int | pa /= 0 OR i >= 0}
  rel_prime_sos_factor_TCC2: OBLIGATION
    FORALL (pa, pb: posnat): rel_prime(pa, pb) IMPLIES pa /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 42, column 71) for  2
      % expected type  {i: int | pb /= 0 OR i >= 0}
  rel_prime_sos_factor_TCC3: OBLIGATION
    FORALL (pa, pb: posnat): rel_prime(pa, pb) IMPLIES pb /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 67, column 53) for  y - x - z
      % expected type  nat
  involution_fermat_set_one_fp_invol_TCC1: OBLIGATION
    FORALL (x, y, z: nat): x < y - z IMPLIES y - x - z >= 0;

  % Subtype TCC generated (at line 68, column 42) for  2 * y - x
      % expected type  nat
  involution_fermat_set_one_fp_invol_TCC2: OBLIGATION
    FORALL (x, y, z: nat):
      y - z <= x AND x <= 2 * y AND NOT x < y - z IMPLIES 2 * y - x >= 0;

  % Subtype TCC generated (at line 68, column 50) for  x - y + z
      % expected type  nat
  involution_fermat_set_one_fp_invol_TCC3: OBLIGATION
    FORALL (x, y, z: nat):
      y - z <= x AND x <= 2 * y AND NOT x < y - z IMPLIES x - y + z >= 0;

  % Subtype TCC generated (at line 69, column 12) for  x - 2 * y
      % expected type  nat
  involution_fermat_set_one_fp_invol_TCC4: OBLIGATION
    FORALL (x, y, z: nat):
      NOT (y - z <= x AND x <= 2 * y) AND NOT x < y - z IMPLIES
       x - 2 * y >= 0;

  % Subtype TCC generated (at line 69, column 18) for  x - y + z
      % expected type  nat
  involution_fermat_set_one_fp_invol_TCC5: OBLIGATION
    FORALL (x, y, z: nat):
      NOT (y - z <= x AND x <= 2 * y) AND NOT x < y - z IMPLIES
       x - y + z >= 0;

  % Subtype TCC generated (at line 76, column 20) for
      % (x + 2 * z, z, y - x - z)
      % expected type  (fermat_prime_sos_set(p))
  invol_fermat_TCC1: OBLIGATION
    FORALL (p: (prime?), xyz: (fermat_prime_sos_set(p)), x: nat, y: nat,
            z: nat):
      x < y - z AND z = xyz`3 AND y = xyz`2 AND x = xyz`1 IMPLIES
       fermat_prime_sos_set(p)(x + 2 * z, z, y - x - z);

  % Subtype TCC generated (at line 77, column 41) for
      % (2 * y - x, y, x - y + z)
      % expected type  (fermat_prime_sos_set(p))
  invol_fermat_TCC2: OBLIGATION
    FORALL (p: (prime?), xyz: (fermat_prime_sos_set(p)), x: nat, y: nat,
            z: nat):
           y - z <= x AND x <= 2 * y AND NOT x < y - z AND z = xyz`3
       AND y = xyz`2 AND x = xyz`1
       IMPLIES fermat_prime_sos_set(p)(2 * y - x, y, x - y + z);

  % Subtype TCC generated (at line 78, column 11) for
      % (x - 2 * y, x - y + z, y)
      % expected type  (fermat_prime_sos_set(p))
  invol_fermat_TCC3: OBLIGATION
    FORALL (p: (prime?), xyz: (fermat_prime_sos_set(p)), x: nat, y: nat,
            z: nat):
           NOT (y - z <= x AND x <= 2 * y) AND NOT x < y - z AND z = xyz`3
       AND y = xyz`2 AND x = xyz`1
       IMPLIES fermat_prime_sos_set(p)(x - 2 * y, x - y + z, y);

  % Subtype TCC generated (at line 87, column 26) for  p
      % expected type  nat
  fermat_prime_mod_4_TCC1: OBLIGATION
    FORALL (p: (prime?)): mod(p, 4) = 1 IMPLIES p >= 0;


body:
  sqrt_two: THEORY
  %-------------------------------------------------------------------------
  % the proof that the square root of two is irrational
  % Author: Alfons Geser, HTWK Leipzig, Germany
  % Date: May, 2009
  %-------------------------------------------------------------------------
  BEGIN

    IMPORTING reals@sqrt, ints@gcd_fractions

    n: VAR nat

    even_or_odd: LEMMA divides(2, n) IFF NOT divides(2, n + 1)

    two_divides_sq: LEMMA divides(2, sq(n)) IFF divides(2, n)

    sqrt2_is_irrational: THEOREM NOT rational_pred(sqrt(2))

  END sqrt_two

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 15, column 35) for  sq(n)
      % expected type  int
  two_divides_sq_TCC1: OBLIGATION
    FORALL (n: nat): rational_pred(sq(n)) AND integer_pred(sq(n));


body:
  infinite_primes: THEORY
  BEGIN
      IMPORTING ints@divides_lems, 
                reals@product_fseq_posnat,
                prime_factorization
      Primes: set[nat] = {n: nat | prime?(n)}

      n: VAR posnat
      prime_divides: LEMMA  NOT prime?(n) AND n > 1 IMPLIES
                                   (EXISTS (p: nat): prime?(p) AND divides(p,n))

      ii: VAR nat
      divides_product: LEMMA FORALL (fs: fseq[posnat]),
                                         (ii: below(length(fs))): 
                                   divides(seq(fs)(ii), product(fs))

      primes_infinite: THEOREM NOT is_finite(Primes)
   
  END infinite_primes


body:
  unique_scaf: THEORY
  BEGIN
   
     IMPORTING prime_factorization, ints@gcd,
               structures@fseqs[posnat]

     fs,fs1,fs2: VAR fseq[posnat]


     n,m: VAR nat
     i,j: VAR int
     p  : VAR (prime?)

     AUTO_REWRITE+ product_eq_arg


     gcd_primes: LEMMA prime?(i) AND prime?(j) AND (i /= 0 OR j /= 0) AND i /= j
                       IMPLIES gcd(i,j) = 1

     len1: LEMMA ordered_list_of_primes?(fs)
                    AND product(fs) = 1 IMPLIES length(fs) = 0 

     len3: LEMMA ordered_list_of_primes?(fs)
                       AND length(fs) > 0 IMPLIES  product(fs) > 1 


  %% The following produces unprovable TCCs for some bizarre reason
  %%
  %%   seq_eq_len: LEMMA m < length(fs1) AND n < length(fs2)  
  %%                     AND fs1 ^ (0, m) = fs2 ^ (0, n) IMPLIES m = n

     ordered_list_of_primes_caret: LEMMA FORALL (n: below(length(fs))): 
                              ordered_list_of_primes?(fs) IMPLIES
                                   ordered_list_of_primes?(fs ^ (0, n))

     IMPORTING product_perm_lems

     k,pn: VAR posnat 
     olop: LEMMA k = pn * m AND prime?(pn) IMPLIES
                    (EXISTS (fs: fseq[posnat]):
                         k = product(fs) AND
                         ordered_list_of_primes?(fs) AND
                         (EXISTS (i: below(length(fs))): seq(fs)(i) = pn))


   
     product_len_eq: LEMMA product(fs1) = product(fs2) AND
                          ordered_list_of_primes?(fs1) AND
                          ordered_list_of_primes?(fs2) AND 
                          length(fs1) = 1
                            IMPLIES length(fs2) = 1

  END unique_scaf

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 18, column 35) for  j
      % expected type  {jj: int | i = 0 => jj /= 0}
  gcd_primes_TCC1: OBLIGATION
    FORALL (i, j: int):
      i /= j AND (i /= 0 OR j /= 0) AND prime?(j) AND prime?(i) IMPLIES
       i = 0 => j /= 0;


body:
  unique_factorization: THEORY
  BEGIN
   
     IMPORTING prime_factorization, unique_scaf

     fs,fs1,fs2: VAR fseq[posnat]


     n,m: VAR nat
     i,j: VAR int


     FTL_sym: LEMMA (FORALL (k: nat):
         k < j
     	IMPLIES
           (FORALL (fs1: fseq[posnat], fs2: fseq[posnat]):
     	 k = product(fs1)
     	     AND k = product(fs2)
     	       AND ordered_list_of_primes?(fs1)
     		 AND ordered_list_of_primes?(fs2) AND k > 1
     	     IMPLIES fs1 = fs2))
        AND j = product(fs1) 
        AND j = product(fs2) 
        AND ordered_list_of_primes?(fs1)
        AND ordered_list_of_primes?(fs2)
        AND j > 1
        AND length(fs2) > 1
        AND length(fs1) > 1
        AND seq(fs2)(length(fs2) - 1) < seq(fs1)(length(fs1) - 1)  
      IMPLIES
          fs1 = fs2

     FTL_prep: THEOREM n = product(fs1) AND n = product(fs2) 
                       AND ordered_list_of_primes?(fs1)
                       AND ordered_list_of_primes?(fs2)
                       AND n > 1 
                               IMPLIES fs1 = fs2

     Fundamental_Theorem_Arithmetic: THEOREM n = product(fs1) AND n = product(fs2)
                                             AND ordered_list_of_primes?(fs1)
                                             AND ordered_list_of_primes?(fs2)    
                                                     IMPLIES fs1 = fs2


  END unique_factorization

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 29, column 19) for  length(fs2) - 1
      % expected type  nat
  FTL_sym_TCC1: OBLIGATION
    FORALL (fs11, fs21: fseq[posnat], j: int):
           FORALL (k: nat):
             k < j IMPLIES
              (FORALL (fs1: fseq[posnat], fs2: fseq[posnat]):
                      k = product(fs1) AND k = product(fs2)
                  AND ordered_list_of_primes?(fs1)
                  AND ordered_list_of_primes?(fs2) AND k > 1
                  IMPLIES fs1 = fs2)
       AND j = product(fs11) AND j = product(fs21)
       AND ordered_list_of_primes?(fs11) AND ordered_list_of_primes?(fs21)
       AND j > 1 AND length(fs21) > 1 AND length(fs11) > 1
       IMPLIES length(fs21) - 1 >= 0;

  % Subtype TCC generated (at line 29, column 47) for  length(fs1) - 1
      % expected type  nat
  FTL_sym_TCC2: OBLIGATION
    FORALL (fs11, fs21: fseq[posnat], j: int):
           FORALL (k: nat):
             k < j IMPLIES
              (FORALL (fs1: fseq[posnat], fs2: fseq[posnat]):
                      k = product(fs1) AND k = product(fs2)
                  AND ordered_list_of_primes?(fs1)
                  AND ordered_list_of_primes?(fs2) AND k > 1
                  IMPLIES fs1 = fs2)
       AND j = product(fs11) AND j = product(fs21)
       AND ordered_list_of_primes?(fs11) AND ordered_list_of_primes?(fs21)
       AND j > 1 AND length(fs21) > 1 AND length(fs11) > 1
       IMPLIES length(fs11) - 1 >= 0;


body:
  %------------------------------------------------------------------------------
  % Generalized Power function (without ln/exp)
  %
  %     Author: David Lester, Manchester University & NIA
  %
  %     Version 1.0            19/08/08   Initial version (DRL)
  %
  % This library provides Roots, Powers and Generalized Logs
  %
  % The (achieved) aim is to avoid using all libraries except those in
  % the standard prelude. Hooks are provided so that the power function
  % along with root and log can be shown to be continuous (over
  % suitable domains), but no continuity libraries have been used to
  % construct this library, meaning that it is built directly onto the
  % standard SRI prelude.
  %
  % Features include:
  % 
  % By INCLUDING root, you can have statements like:
  %
  %   root(8,3) = 2
  %
  % By INCLUDING real_expt, you can have statements like:
  %
  %   8^(1/3) = 2
  %
  % BY INCLUDING log, you can have statements like:
  %
  %   log(2)(8) = 3 /* = ln(8)/ln(2) */
  %
  %------------------------------------------------------------------------------

  top: THEORY

  BEGIN

    IMPORTING rational_props_aux, % Extra properties for prelude
              exponentiation_aux, % Extra properties for prelude
              nn_root,            % nth-roots of nnreals 
              root,               % nth-roots of reals
                                  %  (includes negative reals, for odd n)
              nn_rational_expt,   % x^y (x:nnreal, y: nnrat) Note 0^0 = 1
              nnreal_expt,        % x^y (x,y: nnreal)
              real_expt,          % x^y (x:nnreal, y:real) provided y>=0 when 0^y
              nn_log,             % inverse of nnreal_expt
              log,                % inverse of real_expt
              real_fun_power,     % exponentiation of functions

              ln_exp_def          % linking log to ln and ^ to exp
  END top


body:
  exponentiation_aux: THEORY

  BEGIN

    px: VAR posreal
    n:  VAR nat

    expt_lower_bound: LEMMA 1+n*px <= expt(1+px,n)

  END exponentiation_aux


body:
  %------------------------------------------------------------------------------
  % nth roots of nnreals
  %
  %     Author: David Lester, Manchester University & NIA
  %
  %     Version 1.0            19/08/08   Initial version (DRL)
  %
  % (Note that we have the essentials of continuity proved, without
  %  using of defining these concepts. This means that the definition can
  %  be used stand-alone.)
  %------------------------------------------------------------------------------

  nn_root: THEORY

  BEGIN

    IMPORTING exponentiation_aux

    x,x1,x2,y: VAR nnreal
    epsilon, px,py,
      delta: VAR posreal
    pm,pn:   VAR posnat
    lt1x:    VAR {r:posreal | r < 1}
    gt1x:    VAR {r:posreal | r > 1}

    continuous_alt_hat: LEMMA EXISTS delta: FORALL x2: abs(x1-x2) < delta
                   => abs(x1^pn-x2^pn) < epsilon

    hat_bijective: LEMMA bijective?[nnreal,nnreal](lambda x: x^pn)

    nn_root(x,pn):nnreal = inverse[nnreal,nnreal](lambda x: x^pn)(x)

    nn_root_0n: LEMMA nn_root(0,pn) = 0
    nn_root_1n: LEMMA nn_root(1,pn) = 1
    nn_root_x1: LEMMA nn_root(x,1)  = x

    nn_root_strict_increasing: LEMMA x < y => nn_root(x,pn) < nn_root(y,pn)

    nn_root_expt: LEMMA nn_root(x^pn,pn) = x
    expt_nn_root: LEMMA nn_root(x,pn)^pn = x

    nn_root_is_0: LEMMA nn_root(x,pn) = 0 IFF x = 0
    nn_root_pos:  LEMMA nn_root(px,pn) > 0
    nn_root_gt1:  LEMMA nn_root(x,pn) > 1 IFF x > 1
    nn_root_lt1:  LEMMA nn_root(x,pn) < 1 IFF x < 1

    mult_nn_root: LEMMA nn_root(x*y,pn)  = nn_root(x,pn)*nn_root(y,pn)
    inv_nn_root:  LEMMA nn_root(1/px,pn) = 1/nn_root(px,pn)
    div_nn_root:  LEMMA nn_root(x/py,pn) = nn_root(x,pn)/nn_root(py,pn)

    nn_root_mult: LEMMA nn_root(x,pn*pm)  = nn_root(nn_root(x,pn),pm)

    nn_root_increasing: LEMMA pn < pm AND 0 < x AND x < 1 =>
                               nn_root(x,pn) < nn_root(x,pm)

    nn_root_decreasing: LEMMA pn < pm AND 1 < x =>
                               nn_root(x,pn) > nn_root(x,pm)

    nn_root_upper_bound: LEMMA nn_root(1+px,pn) <= 1+px/pn

    nn_root_bijective: LEMMA bijective?[nnreal,nnreal](lambda x: nn_root(x,pn))

    continuous_alt_nn_root: LEMMA EXISTS delta: FORALL x2: abs(x1-x2) < delta
                   => abs(nn_root(x1,pn)-nn_root(x2,pn)) < epsilon

    both_sides_nn_root_lt: LEMMA nn_root(x,pn) <  nn_root(y,pn) IFF x <  y
    both_sides_nn_root_le: LEMMA nn_root(x,pn) <= nn_root(y,pn) IFF x <= y
    both_sides_nn_root_gt: LEMMA nn_root(x,pn) >  nn_root(y,pn) IFF x >  y
    both_sides_nn_root_ge: LEMMA nn_root(x,pn) >= nn_root(y,pn) IFF x >= y
    both_sides_nn_root:    LEMMA nn_root(x,pn) =  nn_root(y,pn) IFF x =  y

    both_sides_nn_root_lt1_lt: LEMMA
      nn_root(lt1x,pn) <  nn_root(lt1x,pm) IFF pn <  pm
    both_sides_nn_root_lt1_le: LEMMA
      nn_root(lt1x,pn) <= nn_root(lt1x,pm) IFF pn <= pm
    both_sides_nn_root_lt1_gt: LEMMA
      nn_root(lt1x,pn) >  nn_root(lt1x,pm) IFF pn >  pm
    both_sides_nn_root_lt1_ge: LEMMA
      nn_root(lt1x,pn) >= nn_root(lt1x,pm) IFF pn >= pm

    both_sides_nn_root_gt1_lt: LEMMA
      nn_root(gt1x,pn) <  nn_root(gt1x,pm) IFF pm <  pn
    both_sides_nn_root_gt1_le: LEMMA
      nn_root(gt1x,pn) <= nn_root(gt1x,pm) IFF pm <= pn
    both_sides_nn_root_gt1_gt: LEMMA
      nn_root(gt1x,pn) >  nn_root(gt1x,pm) IFF pm >  pn
    both_sides_nn_root_gt1_ge: LEMMA
      nn_root(gt1x,pn) >= nn_root(gt1x,pm) IFF pm >= pn

    both_sides_nn_root_eq: LEMMA nn_root(x,pn) = nn_root(x,pm) IFF
                                 x = 0 OR x = 1 OR pn = pm

  END nn_root

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 27, column 27) for  pn
      % expected type  {i: int | x1 /= 0 OR i >= 0}
  continuous_alt_hat_TCC1: OBLIGATION
    FORALL (pn: posnat, x1: nnreal, delta, x2):
      abs(x1 - x2) < delta IMPLIES x1 /= 0 OR pn >= 0;

  % Subtype TCC generated (at line 27, column 33) for  pn
      % expected type  {i: int | x2 /= 0 OR i >= 0}
  continuous_alt_hat_TCC2: OBLIGATION
    FORALL (pn: posnat, x1: nnreal, delta, x2):
      abs(x1 - x2) < delta IMPLIES x2 /= 0 OR pn >= 0;

  % Subtype TCC generated (at line 29, column 61) for  pn
      % expected type  {i: int | x /= 0 OR i >= 0}
  hat_bijective_TCC1: OBLIGATION FORALL (pn: posnat, x): x /= 0 OR pn >= 0;

  % Subtype TCC generated (at line 40, column 36) for  pn
      % expected type  {i: int | nn_root(x, pn) /= 0 OR i >= 0}
  expt_nn_root_TCC1: OBLIGATION
    FORALL (pn: posnat, x: nnreal): nn_root(x, pn) /= 0 OR pn >= 0;

  % Subtype TCC generated (at line 48, column 43) for  nn_root(px, pn)
      % expected type  nznum
  inv_nn_root_TCC1: OBLIGATION
    FORALL (pn: posnat, px: posreal): nn_root(px, pn) /= 0;


body:
  %------------------------------------------------------------------------------
  % Generalized Root function
  %
  %     Author: David Lester, Manchester University & NIA
  %
  %     Version 1.0            19/08/08   Initial version (DRL)
  %
  % (We can take nth-roots of negative numbers provided n is odd.
  %  I could believe that the type-constraints make this unusable;
  %  feedback appreciated.)
  %------------------------------------------------------------------------------

  root: THEORY

  BEGIN

    IMPORTING reals@sign,
              nn_root

    x,y,z: VAR real
    epsilon,
      delta: VAR posreal
    pm,pn:   VAR posnat
    nx: VAR nnreal

    root(x:real,pn:{pm | x >= 0 OR odd?(pm)}):real = nn_root(abs(x),pn)*sign(x)

    root_0n: LEMMA root(0,pn) = 0
    root_1n: LEMMA root(1,pn) = 1
    root_x1: LEMMA root(x,1)  = x

    root_nn_root_rew: LEMMA root(nx,pn) = nn_root(nx,pn)

    root_expt: LEMMA FORALL (x:real,pn:{pm | x >= 0 OR odd?(pm)}):
                     root(x^pn,pn) = x
    expt_root: LEMMA FORALL (x:real,pn:{pm | x >= 0 OR odd?(pm)}):
                     root(x,pn)^pn = x

    root_is_0: LEMMA FORALL (x:real,pn:{pm | x >= 0 OR odd?(pm)}):
                     root(x,pn) = 0 IFF x = 0
    root_pos:  LEMMA FORALL (x:real,pn:{pm | x >= 0 OR odd?(pm)}):
                     root(x,pn) > 0 IFF x > 0
    root_neg:  LEMMA FORALL (x:real,pn:{pm | x >= 0 OR odd?(pm)}):
                     root(x,pn) < 0 IFF x < 0
    root_gt1:  LEMMA FORALL (x:real,pn:{pm | x >= 0 OR odd?(pm)}):
                     root(x,pn) > 1 IFF x > 1
    root_lt1:  LEMMA FORALL (x:real,pn:{pm | x >= 0 OR odd?(pm)}):
                     root(x,pn) < 1 IFF x < 1

    neg_root:  LEMMA odd?(pn) => root(-x,pn) = -root(x,pn)

    mult_root: LEMMA FORALL (x,y:real,pn:{pm | x >= 0 AND y >= 0 OR odd?(pm)}):
                     root(x*y,pn)  = root(x,pn)*root(y,pn)
    inv_root:  LEMMA FORALL (n0x:nzreal,pn:{pm | n0x >= 0 OR odd?(pm)}):
                     root(1/n0x,pn) = 1/root(n0x,pn)
    div_root:  LEMMA FORALL (x:real,n0y:nzreal,
                             pn:{pm | x >= 0 AND n0y >= 0 OR odd?(pm)}):
                     root(x/n0y,pn) = root(x,pn)/root(n0y,pn)

    root_mult: LEMMA FORALL (x:real,pm,pn:{i:posnat | x >= 0 OR odd?(i)}):
                     root(x,pn*pm)  = root(root(x,pn),pm)

    root_increasing: LEMMA ((0 < x AND x < 1) OR
                            (odd?(pn) AND odd?(pm) AND x < -1)) AND
                           pn < pm => root(x,pn) < root(x,pm)

    root_decreasing: LEMMA (1 < x OR
                            (odd?(pn) AND odd?(pm) AND -1 < x AND x < 0)) AND
                           pn < pm => root(x,pn) > root(x,pm)

    continuous_alt_root:
               LEMMA FORALL (x:real,epsilon:posreal,
                             pn:{pm | x >= 0 AND y >= 0 OR odd?(pm)}):
                     EXISTS delta: FORALL (y:{z | z >= 0 OR odd?(pn)}):
                                  abs(x-y) < delta
                                   => abs(root(x,pn)-root(y,pn)) < epsilon

  END root

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 32, column 34) for  pn
      % expected type  {pm | nx >= 0 OR odd?(pm)}
  root_nn_root_rew_TCC1: OBLIGATION
    FORALL (nx: nnreal, pn: posnat): nx >= 0 OR odd?(pn);

  % Subtype TCC generated (at line 35, column 26) for  pn
      % expected type  {i: int | x /= 0 OR i >= 0}
  root_expt_TCC1: OBLIGATION
    FORALL (x: real, pn: {pm | x >= 0 OR odd?(pm)}): x /= 0 OR pn >= 0;

  % Subtype TCC generated (at line 35, column 29) for  pn
      % expected type  {pm | x ^ pn >= 0 OR odd?(pm)}
  root_expt_TCC2: OBLIGATION
    FORALL (x: real, pn: {pm | x >= 0 OR odd?(pm)}): x ^ pn >= 0 OR odd?(pn);

  % Subtype TCC generated (at line 37, column 30) for  pn
      % expected type  {i: int | root(x, pn) /= 0 OR i >= 0}
  expt_root_TCC1: OBLIGATION
    FORALL (x: real, pn: {pm | x >= 0 OR odd?(pm)}):
      root(x, pn) /= 0 OR pn >= 0;

  % Subtype TCC generated (at line 50, column 39) for  pn
      % expected type  {pm | -x >= 0 OR odd?(pm)}
  neg_root_TCC1: OBLIGATION
    FORALL (pn: posnat, x: real): odd?(pn) IMPLIES -x >= 0 OR odd?(pn);

  % Subtype TCC generated (at line 50, column 53) for  pn
      % expected type  {pm | x >= 0 OR odd?(pm)}
  neg_root_TCC2: OBLIGATION
    FORALL (pn: posnat, x: real): odd?(pn) IMPLIES x >= 0 OR odd?(pn);

  % Subtype TCC generated (at line 53, column 28) for  pn
      % expected type  {pm | x * y >= 0 OR odd?(pm)}
  mult_root_TCC1: OBLIGATION
    FORALL (x, y: real, pn: {pm | x >= 0 AND y >= 0 OR odd?(pm)}):
      x * y >= 0 OR odd?(pn);

  % Subtype TCC generated (at line 53, column 42) for  pn
      % expected type  {pm | x >= 0 OR odd?(pm)}
  mult_root_TCC2: OBLIGATION
    FORALL (x, y: real, pn: {pm | x >= 0 AND y >= 0 OR odd?(pm)}):
      x >= 0 OR odd?(pn);

  % Subtype TCC generated (at line 53, column 53) for  pn
      % expected type  {pm | y >= 0 OR odd?(pm)}
  mult_root_TCC3: OBLIGATION
    FORALL (x, y: real, pn: {pm | x >= 0 AND y >= 0 OR odd?(pm)}):
      y >= 0 OR odd?(pn);

  % Subtype TCC generated (at line 55, column 30) for  pn
      % expected type  {pm | 1 / n0x >= 0 OR odd?(pm)}
  inv_root_TCC1: OBLIGATION
    FORALL (n0x: nzreal, pn: {pm | n0x >= 0 OR odd?(pm)}):
      1 / n0x >= 0 OR odd?(pn);

  % Subtype TCC generated (at line 55, column 38) for  root(n0x, pn)
      % expected type  nznum
  inv_root_TCC2: OBLIGATION
    FORALL (n0x: nzreal, pn: {pm | n0x >= 0 OR odd?(pm)}): root(n0x, pn) /= 0;

  % Subtype TCC generated (at line 58, column 30) for  pn
      % expected type  {pm | x / n0y >= 0 OR odd?(pm)}
  div_root_TCC1: OBLIGATION
    FORALL (x: real, n0y: nzreal,
            pn: {pm | x >= 0 AND n0y >= 0 OR odd?(pm)}):
      x / n0y >= 0 OR odd?(pn);

  % Subtype TCC generated (at line 58, column 43) for  pn
      % expected type  {pm | x >= 0 OR odd?(pm)}
  div_root_TCC2: OBLIGATION
    FORALL (x: real, n0y: nzreal,
            pn: {pm | x >= 0 AND n0y >= 0 OR odd?(pm)}):
      x >= 0 OR odd?(pn);

  % Subtype TCC generated (at line 58, column 56) for  pn
      % expected type  {pm | n0y >= 0 OR odd?(pm)}
  div_root_TCC3: OBLIGATION
    FORALL (x: real, n0y: nzreal,
            pn: {pm | x >= 0 AND n0y >= 0 OR odd?(pm)}):
      n0y >= 0 OR odd?(pn);

  % Subtype TCC generated (at line 58, column 47) for  root(n0y, pn)
      % expected type  nznum
  div_root_TCC4: OBLIGATION
    FORALL (x: real, n0y: nzreal,
            pn: {pm | x >= 0 AND n0y >= 0 OR odd?(pm)}):
      root(n0y, pn) /= 0;

  % Subtype TCC generated (at line 61, column 26) for  pn * pm
      % expected type  {pm | x >= 0 OR odd?(pm)}
  root_mult_TCC1: OBLIGATION
    FORALL (x: real, pm, pn: {i: posnat | x >= 0 OR odd?(i)}):
      x >= 0 OR odd?(pn * pm);

  % Subtype TCC generated (at line 61, column 52) for  pm
      % expected type  {pm | root(x, pn) >= 0 OR odd?(pm)}
  root_mult_TCC2: OBLIGATION
    FORALL (x: real, pm, pn: {i: posnat | x >= 0 OR odd?(i)}):
      root(x, pn) >= 0 OR odd?(pm);

  % Subtype TCC generated (at line 65, column 43) for  pn
      % expected type  {pm | x >= 0 OR odd?(pm)}
  root_increasing_TCC1: OBLIGATION
    FORALL (pm, pn: posnat, x: real):
      pn < pm AND ((0 < x AND x < 1) OR (odd?(pn) AND odd?(pm) AND x < -1))
       IMPLIES x >= 0 OR odd?(pn);

  % Subtype TCC generated (at line 65, column 56) for  pm
      % expected type  {pm | x >= 0 OR odd?(pm)}
  root_increasing_TCC2: OBLIGATION
    FORALL (pm, pn: posnat, x: real):
      pn < pm AND ((0 < x AND x < 1) OR (odd?(pn) AND odd?(pm) AND x < -1))
       IMPLIES x >= 0 OR odd?(pm);

  % Subtype TCC generated (at line 69, column 43) for  pn
      % expected type  {pm | x >= 0 OR odd?(pm)}
  root_decreasing_TCC1: OBLIGATION
    FORALL (pm, pn: posnat, x: real):
      pn < pm AND (1 < x OR (odd?(pn) AND odd?(pm) AND -1 < x AND x < 0))
       IMPLIES x >= 0 OR odd?(pn);

  % Subtype TCC generated (at line 69, column 56) for  pm
      % expected type  {pm | x >= 0 OR odd?(pm)}
  root_decreasing_TCC2: OBLIGATION
    FORALL (pm, pn: posnat, x: real):
      pn < pm AND (1 < x OR (odd?(pn) AND odd?(pm) AND -1 < x AND x < 0))
       IMPLIES x >= 0 OR odd?(pm);

  % Subtype TCC generated (at line 76, column 47) for  pn
      % expected type  {pm | x >= 0 OR odd?(pm)}
  continuous_alt_root_TCC1: OBLIGATION
    FORALL (y1, x: real, pn: {pm | x >= 0 AND y1 >= 0 OR odd?(pm)}, delta,
            y: {z | z >= 0 OR odd?(pn)}):
      abs(x - y) < delta IMPLIES x >= 0 OR odd?(pn);

  % Subtype TCC generated (at line 76, column 58) for  pn
      % expected type  {pm | y >= 0 OR odd?(pm)}
  continuous_alt_root_TCC2: OBLIGATION
    FORALL (y1, x: real, pn: {pm | x >= 0 AND y1 >= 0 OR odd?(pm)}, delta,
            y: {z | z >= 0 OR odd?(pn)}):
      abs(x - y) < delta IMPLIES y >= 0 OR odd?(pn);


body:
  %------------------------------------------------------------------------------
  % Extensions for prelude library: rational_props
  %
  %     Author: David Lester, Manchester University & NIA
  %
  %     Version 1.0            19/08/08   Initial version (DRL)
  %
  % Extensions to standard prelude library "rational_props"
  %
  % Note to Sam:
  %
  % It may be that "min" is declared _after_ rational_props, in which
  % case this will not work. Otherwise it ought to be fine.
  %
  %------------------------------------------------------------------------------

  rational_props_aux: THEORY

  BEGIN

    p: VAR posnat
    r: VAR rat
    i: VAR int

    denominator(r):posnat = min({p | integer_pred(r*p)}) 
    numerator(r):int      = r*denominator(r)

    rational_def:      LEMMA numerator(r)/denominator(r) = r

    denominator_int:   LEMMA denominator(i) = 1
    numerator_int:     LEMMA numerator(i)   = i

    numerator_is_zero: LEMMA numerator(r) = 0 IFF r = 0
    numerator_pos:     LEMMA numerator(r) > 0 IFF r > 0
    numerator_neg:     LEMMA numerator(r) < 0 IFF r < 0

  END rational_props_aux

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 25, column 30) for
      % {p | integer_pred(r * p)}
      % expected type  S: (nonempty?[posnat])
  denominator_TCC1: OBLIGATION
    FORALL (r: rat): nonempty?[posnat]({p | integer_pred(r * p)});

  % Subtype TCC generated (at line 26, column 26) for  r * denominator(r)
      % expected type  int
  numerator_TCC1: OBLIGATION
    FORALL (r: rat): integer_pred(r * denominator(r));


body:
  %------------------------------------------------------------------------------
  % Power function for nnx^nnq
  %
  %     Author: David Lester, Manchester University & NIA
  %
  %     Version 1.0            19/08/08   Initial version (DRL)
  %------------------------------------------------------------------------------

  nn_rational_expt: THEORY

  BEGIN

    IMPORTING rational_props_aux,
              nn_root

    x,y,z,x1,x2: VAR nnreal  
    px,py,epsilon,delta:   VAR posreal
    q,r:     VAR nnrat
    pq:      VAR posrat
    n:       VAR nat
    pn:      VAR posnat

    nn_rational_expt(x,q):nnreal = nn_root(expt(x,numerator(q)),denominator(q))

    nn_rational_expt_nat_rew:  LEMMA nn_rational_expt(x,n)    = x^n
    nn_rational_expt_root_rew: LEMMA nn_rational_expt(x,1/pn) = nn_root(x,pn)
    nn_rational_expt_rat_rew:  LEMMA nn_rational_expt(x,n/pn) = nn_root(x^n,pn)

    nn_rational_expt_strict_increasing: LEMMA x < y =>
                                 nn_rational_expt(x,pq) <  nn_rational_expt(y,pq)

    nn_rational_expt_0q: LEMMA nn_rational_expt(0,q)
                                = IF q = 0 THEN 1 ELSE 0 ENDIF
    nn_rational_expt_1q: LEMMA nn_rational_expt(1,q) = 1
    nn_rational_expt_x1: LEMMA nn_rational_expt(x,1) = x

    nn_rational_expt_is_0: LEMMA nn_rational_expt(x,q) = 0 IFF x = 0 AND q /= 0
    nn_rational_expt_pos:  LEMMA nn_rational_expt(px,q) > 0
    nn_rational_expt_gt1:  LEMMA nn_rational_expt(x,pq) > 1 IFF x > 1
    nn_rational_expt_lt1:  LEMMA nn_rational_expt(x,pq) < 1 IFF x < 1

    mult_nn_rational_expt: LEMMA nn_rational_expt(x*y,q)
                                 = nn_rational_expt(x,q)*nn_rational_expt(y,q)
    inv_nn_rational_expt:  LEMMA nn_rational_expt(1/px,q)
                                 = 1/nn_rational_expt(px,q)
    div_nn_rational_expt:  LEMMA nn_rational_expt(x/py,q)
                                 = nn_rational_expt(x,q)/nn_rational_expt(py,q)

    nn_rational_expt_plus: LEMMA nn_rational_expt(x,q+r)
                                 = nn_rational_expt(x,q)*nn_rational_expt(x,r)
    nn_rational_expt_times:LEMMA nn_rational_expt(x,q*r)
                                 = nn_rational_expt(nn_rational_expt(x,q),r)

    nn_rational_expt_decreasing: LEMMA q < r AND 0 < x AND x < 1 =>
                               nn_rational_expt(x,q) > nn_rational_expt(x,r)

    nn_rational_expt_increasing: LEMMA q < r AND 1 < x =>
                               nn_rational_expt(x,q) < nn_rational_expt(x,r)

    nn_rational_expt_def: LEMMA
         nn_rational_expt(x,q) = expt(nn_root(x,denominator(q)),numerator(q))

    continuous_alt_nn_rational_expt: LEMMA
       EXISTS delta: FORALL x2: abs(x1-x2) < delta
                  => abs(nn_rational_expt(x1,q)-nn_rational_expt(x2,q)) < epsilon

    nn_rational_expt_approx_gt1: LEMMA
       x > 1 AND y > 1 => EXISTS q: abs(nn_rational_expt(x,q)-y) < epsilon

  END nn_rational_expt

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 23, column 48) for  numerator(q)
      % expected type  nat
  nn_rational_expt_TCC1: OBLIGATION FORALL (q: nnrat): numerator(q) >= 0;

  % Subtype TCC generated (at line 25, column 64) for  n
      % expected type  {i: int | x /= 0 OR i >= 0}
  nn_rational_expt_nat_rew_TCC1: OBLIGATION
    FORALL (n: nat, x: nnreal): x /= 0 OR n >= 0;

  % Subtype TCC generated (at line 45, column 35) for  nn_rational_expt(px, q)
      % expected type  nznum
  inv_nn_rational_expt_TCC1: OBLIGATION
    FORALL (px: posreal, q: nnrat): nn_rational_expt(px, q) /= 0;


body:
  %------------------------------------------------------------------------------
  % Power function nnx^nny
  %
  %     Author: David Lester, Manchester University & NIA
  %
  %     Version 1.0            19/08/08   Initial version (DRL)
  %------------------------------------------------------------------------------

  nnreal_expt: THEORY

  BEGIN

    IMPORTING rational_props_aux,
              nn_root,
              nn_rational_expt

    n:         VAR nat
    pn:        VAR posnat
    a,b,x,y,z: VAR nnreal  
    q:         VAR nnrat
    px,py,pa,pb,
    delta,r,
    epsilon:   VAR posreal

    nnreal_expt(x,y):nnreal
     = IF y = 0 OR x = 1 THEN 1
       ELSIF x < 1 THEN glb({z | EXISTS q: q <= y AND z = nn_rational_expt(x,q)})
                   ELSE lub({z | EXISTS q: q <= y AND z = nn_rational_expt(x,q)})
       ENDIF

    nnreal_expt_rat_rew:  LEMMA nnreal_expt(x,q)    = nn_rational_expt(x,q)
    nnreal_expt_nat_rew:  LEMMA nnreal_expt(x,n)    = x^n
    nnreal_expt_root_rew: LEMMA nnreal_expt(x,1/pn) = nn_root(x,pn)

    nnreal_expt_0a:   LEMMA nnreal_expt(0,a) = IF a = 0 THEN 1 ELSE 0 ENDIF
    nnreal_expt_1a:   LEMMA nnreal_expt(1,a) = 1
    nnreal_expt_x1:   LEMMA nnreal_expt(x,1)  = x

    nnreal_expt_pos:  LEMMA nnreal_expt(px,a) > 0
    nnreal_expt_is_0: LEMMA nnreal_expt(x,a) = 0 IFF x = 0 AND a /= 0
    nnreal_expt_gt1:  LEMMA nnreal_expt(x,pa) > 1 IFF x > 1
    nnreal_expt_lt1:  LEMMA nnreal_expt(x,pa) < 1 IFF x < 1

    inv_nnreal_expt:  LEMMA nnreal_expt(1/px,a) = 1/nnreal_expt(px,a)
    mult_nnreal_expt: LEMMA nnreal_expt(x*y,a)
                                 = nnreal_expt(x,a)*nnreal_expt(y,a)
    div_nnreal_expt:  LEMMA nnreal_expt(x/py,a)
                                 = nnreal_expt(x,a)/nnreal_expt(py,a)

    nnreal_expt_decreasing: LEMMA a < b AND 0 < x AND x < 1 =>
                                  nnreal_expt(x,a) > nnreal_expt(x,b)

    nnreal_expt_increasing: LEMMA a < b AND 1 < x =>
                                  nnreal_expt(x,a) < nnreal_expt(x,b)

    nnreal_expt_strict_increasing: LEMMA x < y =>
                                         nnreal_expt(x,pa) < nnreal_expt(y,pa)

    continuous_alt_nnreal_expt2: LEMMA
       EXISTS delta: FORALL pb: abs(pa-pb) < delta
                   => abs(nnreal_expt(x,pa)-nnreal_expt(x,pb)) < epsilon

    ne1x: VAR {r | r /= 1}
    gt1x: VAR {r | r > 1}
    lt1x: VAR {r | r < 1}

    nnreal_bijective1: LEMMA 
       bijective?[nnreal,{r | r>=1}](lambda y: nnreal_expt(gt1x,y))

    nnreal_bijective2: LEMMA
       bijective?[nnreal,{r | r<=1}](lambda y: nnreal_expt(lt1x,y))

    nnreal_expt_def_gt1: LEMMA
       nnreal_expt(gt1x,py)
            = lub({z | EXISTS q: q < py AND z = nn_rational_expt(gt1x,q)})

    nnreal_expt_plus: LEMMA nnreal_expt(x,a+b)= nnreal_expt(x,a)*nnreal_expt(x,b)
    nnreal_expt_times: LEMMA nnreal_expt(x,a*b) = nnreal_expt(nnreal_expt(x,a),b)

  END nnreal_expt

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 27, column 26) for
      % extend[real, nnreal, bool, FALSE]
      %     ({z | EXISTS q: q <= y AND z = nn_rational_expt(x, q)})
      % expected type  SB: (bounded_below?)
  nnreal_expt_TCC1: OBLIGATION
    FORALL (x: nnreal, y: nnreal):
      x < 1 AND NOT y = 0 AND NOT x = 1 IMPLIES
       nonempty?[real]
           (extend[real, nnreal, bool, FALSE]
                ({z | EXISTS q: q <= y AND z = nn_rational_expt(x, q)}))
        AND
        bounded_below?(extend[real, nnreal, bool, FALSE]
                           ({z |
                               EXISTS q:
                                 q <= y AND z = nn_rational_expt(x, q)}));

  % Subtype TCC generated (at line 27, column 22) for
      % glb(extend[real, nnreal, bool, FALSE]
      %         ({z | EXISTS q: q <= y AND z = nn_rational_expt(x, q)}))
      % expected type  nnreal
  nnreal_expt_TCC2: OBLIGATION
    FORALL (x: nnreal, y: nnreal):
      x < 1 AND NOT y = 0 AND NOT x = 1 IMPLIES
       glb(extend[real, nnreal, bool, FALSE]
               ({z | EXISTS q: q <= y AND z = nn_rational_expt(x, q)}))
        >= 0;

  % Subtype TCC generated (at line 28, column 26) for
      % extend[real, nnreal, bool, FALSE]
      %     ({z | EXISTS q: q <= y AND z = nn_rational_expt(x, q)})
      % expected type  SA: (bounded_above?)
  nnreal_expt_TCC3: OBLIGATION
    FORALL (x: nnreal, y: nnreal):
      NOT x < 1 AND NOT y = 0 AND NOT x = 1 IMPLIES
       nonempty?[real]
           (extend[real, nnreal, bool, FALSE]
                ({z | EXISTS q: q <= y AND z = nn_rational_expt(x, q)}))
        AND
        bounded_above?(extend[real, nnreal, bool, FALSE]
                           ({z |
                               EXISTS q:
                                 q <= y AND z = nn_rational_expt(x, q)}));

  % Subtype TCC generated (at line 28, column 22) for
      % lub(extend[real, nnreal, bool, FALSE]
      %         ({z | EXISTS q: q <= y AND z = nn_rational_expt(x, q)}))
      % expected type  nnreal
  nnreal_expt_TCC4: OBLIGATION
    FORALL (x: nnreal, y: nnreal):
      NOT x < 1 AND NOT y = 0 AND NOT x = 1 IMPLIES
       lub(extend[real, nnreal, bool, FALSE]
               ({z | EXISTS q: q <= y AND z = nn_rational_expt(x, q)}))
        >= 0;

  % Subtype TCC generated (at line 32, column 54) for  n
      % expected type  {i: int | x /= 0 OR i >= 0}
  nnreal_expt_nat_rew_TCC1: OBLIGATION
    FORALL (n: nat, x: nnreal): x /= 0 OR n >= 0;

  % Subtype TCC generated (at line 44, column 50) for  nnreal_expt(px, a)
      % expected type  nznum
  inv_nnreal_expt_TCC1: OBLIGATION
    FORALL (a: nnreal, px: posreal): nnreal_expt(px, a) /= 0;

  % Subtype TCC generated (at line 68, column 45) for  nnreal_expt(gt1x, y)
      % expected type  {r | r >= 1}
  nnreal_bijective1_TCC1: OBLIGATION
    FORALL (gt1x: {r | r > 1}, y):
      nnreal_expt(gt1x, y) > 0 AND nnreal_expt(gt1x, y) >= 1;

  % Subtype TCC generated (at line 71, column 45) for  nnreal_expt(lt1x, y)
      % expected type  {r | r <= 1}
  nnreal_bijective2_TCC1: OBLIGATION
    FORALL (lt1x: {r | r < 1}, y):
      nnreal_expt(lt1x, y) > 0 AND nnreal_expt(lt1x, y) <= 1;

  % Subtype TCC generated (at line 75, column 16) for
      % extend[real, nnreal, bool, FALSE]
      %     ({z | EXISTS q: q < py AND z = nn_rational_expt(gt1x, q)})
      % expected type  SA: (bounded_above?)
  nnreal_expt_def_gt1_TCC1: OBLIGATION
    FORALL (gt1x: {r | r > 1}, py: posreal):
      nonempty?[real]
          (extend[real, nnreal, bool, FALSE]
               ({z | EXISTS q: q < py AND z = nn_rational_expt(gt1x, q)}))
       AND
       bounded_above?(extend[real, nnreal, bool, FALSE]
                          ({z |
                              EXISTS q:
                                q < py AND z = nn_rational_expt(gt1x, q)}));


body:
  %------------------------------------------------------------------------------
  % Generalized Power function (without ln/exp)
  %
  %     Author: David Lester, Manchester University & NIA
  %
  %     Version 1.0            19/08/08   Initial version (DRL)
  %
  % (Note: we follow the prelude, and define 0^0 = 1)
  %
  %------------------------------------------------------------------------------

  real_expt: THEORY

  BEGIN

    IMPORTING nnreal_expt,
              root

    x,y: VAR nnreal
    a,b: VAR real
    i:   VAR int
    pn:  VAR posnat
    na:  VAR negreal
    n0x: VAR nzreal
    pa,pb,px,py,r: VAR posreal
    gt1x: VAR {r | r > 1}
    lt1x: VAR {r | r < 1}

    ^(x:nnreal,a:{a | a >= 0 OR x > 0}):nnreal
       = IF a >= 0 THEN nnreal_expt(x,a) ELSE nnreal_expt(1/x,-a) ENDIF

    real_expt_nnreal_rew: LEMMA x^y = nnreal_expt(x,y)
    real_expt_int_rew:    LEMMA FORALL (i:{i | x /= 0 OR i >= 0}):
                                x^i = exponentiation.^(x,i)
    real_expt_root_rew:   LEMMA x^(1/pn) = root(x,pn)

    real_expt_x0: LEMMA x^0 = 1
    real_expt_1a: LEMMA 1^a = 1
    real_expt_0x: LEMMA 0^x = IF x = 0 THEN 1 ELSE 0 ENDIF
    real_expt_x1: LEMMA x^1 = x

    real_expt_pos:  LEMMA px^a > 0
    real_expt_is_0: LEMMA FORALL (x:nnreal,a:{a | a >= 0 OR x > 0}):
                          x^a = 0 IFF x = 0 AND a > 0
    real_expt_gt1:  LEMMA FORALL (x:nnreal,a:{a | a >= 0 OR x > 0}):
                          x^a > 1 IFF (x > 1 AND a > 0 OR x < 1 AND a < 0)
    real_expt_lt1:  LEMMA FORALL (x:nnreal,a:{a | a >= 0 OR x > 0}):
                          x^a < 1 IFF (x < 1 AND a > 0 OR x > 1 AND a < 0)

    inv_real_expt:  LEMMA (1/px)^a  = 1/(px^a)
    mult_real_expt: LEMMA FORALL (x,y:nnreal,a:{a | a >= 0 OR x > 0 AND y > 0}):
                          (x*y)^a   = x^a * y^a
    div_real_expt:  LEMMA FORALL (x:nnreal,py:posreal,a:{a | a >= 0 OR x > 0}):
                          (x/py)^a = x^a / py^a

    real_expt_neg:  LEMMA px^(-a)  = (1/px)^a
    real_expt_plus: LEMMA FORALL (x:nnreal,a,b:{a | a >= 0 OR x > 0}):
                          x^(a+b) = x^a * x^b
    real_expt_minus:LEMMA px^(a-b) = px^a / px^b
    real_expt_times:LEMMA FORALL (x:nnreal,a:{a | a >= 0 OR x > 0},
                                           b:{b | b >= 0 OR x^a > 0}):
                          x^(a*b) = (x^a)^b

    real_expt_decreasing:        LEMMA a < b => lt1x^a > lt1x^b
    real_expt_increasing:        LEMMA a < b => gt1x^a < gt1x^b
    real_expt_strict_increasing: LEMMA x < y => x^pa < y^pa
    real_expt_strict_decreasing: LEMMA px < y => px^na > y^na

    both_sides_real_expt_lt: LEMMA x^pa <  y^pa IFF x <  y
    both_sides_real_expt_le: LEMMA x^pa <= y^pa IFF x <= y
    both_sides_real_expt_gt: LEMMA x^pa >  y^pa IFF x >  y
    both_sides_real_expt_ge: LEMMA x^pa >= y^pa IFF x >= y
    both_sides_real_expt:    LEMMA x^pa =  y^pa IFF x =  y

    both_sides_real_expt_lt1_lt: LEMMA lt1x^a <  lt1x^b IFF b <  a
    both_sides_real_expt_lt1_le: LEMMA lt1x^a <= lt1x^b IFF b <= a
    both_sides_real_expt_lt1_gt: LEMMA lt1x^a >  lt1x^b IFF b >  a
    both_sides_real_expt_lt1_ge: LEMMA lt1x^a >= lt1x^b IFF b >= a

    both_sides_real_expt_gt1_lt: LEMMA gt1x^a <  gt1x^b IFF a <  b
    both_sides_real_expt_gt1_le: LEMMA gt1x^a <= gt1x^b IFF a <= b
    both_sides_real_expt_gt1_gt: LEMMA gt1x^a >  gt1x^b IFF a >  b
    both_sides_real_expt_gt1_ge: LEMMA gt1x^a >= gt1x^b IFF a >= b

    both_sides_real_expt_eq: LEMMA x^pa = x^pb IFF x = 0 OR x = 1 OR pa = pb

  END real_expt

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 30, column 58) for  x
      % expected type  nznum
  caret_TCC1: OBLIGATION
    FORALL (x: nnreal, a: {a | a >= 0 OR x > 0}): NOT a >= 0 IMPLIES x /= 0;

  % Subtype TCC generated (at line 30, column 56) for  1 / x
      % expected type  nnreal
  caret_TCC2: OBLIGATION
    FORALL (x: nnreal, a: {a | a >= 0 OR x > 0}):
      NOT a >= 0 IMPLIES 1 / x >= 0;

  % Subtype TCC generated (at line 30, column 60) for  -a
      % expected type  nnreal
  caret_TCC3: OBLIGATION
    FORALL (x: nnreal, a: {a | a >= 0 OR x > 0}): NOT a >= 0 IMPLIES -a >= 0;

  % Subtype TCC generated (at line 32, column 32) for  y
      % expected type  {a | a >= 0 OR x > 0}
  real_expt_nnreal_rew_TCC1: OBLIGATION
    FORALL (x, y: nnreal): y >= 0 OR x > 0;

  % Subtype TCC generated (at line 34, column 32) for  i
      % expected type  {a | a >= 0 OR x > 0}
  real_expt_int_rew_TCC1: OBLIGATION
    FORALL (x: nnreal, i: {i | x /= 0 OR i >= 0}): i >= 0 OR x > 0;

  % Subtype TCC generated (at line 35, column 33) for  (1 / pn)
      % expected type  {a | a >= 0 OR x > 0}
  real_expt_root_rew_TCC1: OBLIGATION
    FORALL (pn: posnat, x: nnreal): (1 / pn) >= 0 OR x > 0;

  % Subtype TCC generated (at line 35, column 48) for  pn
      % expected type  {pm | x >= 0 OR odd?(pm)}
  real_expt_root_rew_TCC2: OBLIGATION
    FORALL (pn: posnat, x: nnreal): x >= 0 OR odd?(pn);

  % Subtype TCC generated (at line 37, column 24) for  0
      % expected type  {a | a >= 0 OR x > 0}
  real_expt_x0_TCC1: OBLIGATION FORALL (x: nnreal): 0 >= 0 OR x > 0;

  % Subtype TCC generated (at line 40, column 24) for  1
      % expected type  {a | a >= 0 OR x > 0}
  real_expt_x1_TCC1: OBLIGATION FORALL (x: nnreal): 1 >= 0 OR x > 0;

  % Subtype TCC generated (at line 42, column 27) for  a
      % expected type  {a | a >= 0 OR px > 0}
  real_expt_pos_TCC1: OBLIGATION
    FORALL (a: real, px: posreal): a >= 0 OR px > 0;

  % Subtype TCC generated (at line 50, column 31) for  a
      % expected type  {a | a >= 0 OR (1 / px) > 0}
  inv_real_expt_TCC1: OBLIGATION
    FORALL (a: real, px: posreal): a >= 0 OR (1 / px) > 0;

  % Subtype TCC generated (at line 50, column 39) for  (px ^ a)
      % expected type  nznum
  inv_real_expt_TCC2: OBLIGATION FORALL (a: real, px: posreal): (px ^ a) /= 0;

  % Subtype TCC generated (at line 52, column 30) for  a
      % expected type  {a | a >= 0 OR (x * y) > 0}
  mult_real_expt_TCC1: OBLIGATION
    FORALL (x, y: nnreal, a: {a | a >= 0 OR x > 0 AND y > 0}):
      a >= 0 OR (x * y) > 0;

  % Subtype TCC generated (at line 52, column 38) for  a
      % expected type  {a | a >= 0 OR x > 0}
  mult_real_expt_TCC2: OBLIGATION
    FORALL (x, y: nnreal, a: {a | a >= 0 OR x > 0 AND y > 0}):
      a >= 0 OR x > 0;

  % Subtype TCC generated (at line 52, column 44) for  a
      % expected type  {a | a >= 0 OR y > 0}
  mult_real_expt_TCC3: OBLIGATION
    FORALL (x, y: nnreal, a: {a | a >= 0 OR x > 0 AND y > 0}):
      a >= 0 OR y > 0;

  % Subtype TCC generated (at line 54, column 31) for  a
      % expected type  {a | a >= 0 OR (x / py) > 0}
  div_real_expt_TCC1: OBLIGATION
    FORALL (x: nnreal, py: posreal, a: {a | a >= 0 OR x > 0}):
      a >= 0 OR (x / py) > 0;

  % Subtype TCC generated (at line 56, column 28) for  (-a)
      % expected type  {a | a >= 0 OR px > 0}
  real_expt_neg_TCC1: OBLIGATION
    FORALL (a: real, px: posreal): (-a) >= 0 OR px > 0;

  % Subtype TCC generated (at line 58, column 27) for  (a + b)
      % expected type  {a | a >= 0 OR x > 0}
  real_expt_plus_TCC1: OBLIGATION
    FORALL (x: nnreal, a, b: {a | a >= 0 OR x > 0}): (a + b) >= 0 OR x > 0;

  % Subtype TCC generated (at line 59, column 28) for  (a - b)
      % expected type  {a | a >= 0 OR px > 0}
  real_expt_minus_TCC1: OBLIGATION
    FORALL (a, b: real, px: posreal): (a - b) >= 0 OR px > 0;

  % Subtype TCC generated (at line 62, column 27) for  (a * b)
      % expected type  {a | a >= 0 OR x > 0}
  real_expt_times_TCC1: OBLIGATION
    FORALL (x: nnreal, a: {a | a >= 0 OR x > 0},
            b: {b | b >= 0 OR x ^ a > 0}):
      (a * b) >= 0 OR x > 0;

  % Subtype TCC generated (at line 64, column 51) for  a
      % expected type  {a | a >= 0 OR lt1x > 0}
  real_expt_decreasing_TCC1: OBLIGATION
    FORALL (a, b: real, lt1x: {r | r < 1}): a < b IMPLIES a >= 0 OR lt1x > 0;

  % Subtype TCC generated (at line 64, column 60) for  b
      % expected type  {a | a >= 0 OR lt1x > 0}
  real_expt_decreasing_TCC2: OBLIGATION
    FORALL (a, b: real, lt1x: {r | r < 1}): a < b IMPLIES b >= 0 OR lt1x > 0;

  % Subtype TCC generated (at line 65, column 51) for  a
      % expected type  {a | a >= 0 OR gt1x > 0}
  real_expt_increasing_TCC1: OBLIGATION
    FORALL (a, b: real, gt1x: {r | r > 1}): a < b IMPLIES a >= 0 OR gt1x > 0;

  % Subtype TCC generated (at line 65, column 60) for  b
      % expected type  {a | a >= 0 OR gt1x > 0}
  real_expt_increasing_TCC2: OBLIGATION
    FORALL (a, b: real, gt1x: {r | r > 1}): a < b IMPLIES b >= 0 OR gt1x > 0;

  % Subtype TCC generated (at line 66, column 48) for  pa
      % expected type  {a | a >= 0 OR x > 0}
  real_expt_strict_increasing_TCC1: OBLIGATION
    FORALL (pa: posreal, x, y: nnreal): x < y IMPLIES pa >= 0 OR x > 0;

  % Subtype TCC generated (at line 66, column 55) for  pa
      % expected type  {a | a >= 0 OR y > 0}
  real_expt_strict_increasing_TCC2: OBLIGATION
    FORALL (pa: posreal, x, y: nnreal): x < y IMPLIES pa >= 0 OR y > 0;

  % Subtype TCC generated (at line 67, column 50) for  na
      % expected type  {a | a >= 0 OR px > 0}
  real_expt_strict_decreasing_TCC1: OBLIGATION
    FORALL (na: negreal, px: posreal, y: nnreal):
      px < y IMPLIES na >= 0 OR px > 0;

  % Subtype TCC generated (at line 67, column 57) for  na
      % expected type  {a | a >= 0 OR y > 0}
  real_expt_strict_decreasing_TCC2: OBLIGATION
    FORALL (na: negreal, px: posreal, y: nnreal):
      px < y IMPLIES na >= 0 OR y > 0;

  % Subtype TCC generated (at line 69, column 35) for  pa
      % expected type  {a | a >= 0 OR x > 0}
  both_sides_real_expt_lt_TCC1: OBLIGATION
    FORALL (pa: posreal, x: nnreal): pa >= 0 OR x > 0;

  % Subtype TCC generated (at line 75, column 42) for  a
      % expected type  {a | a >= 0 OR lt1x > 0}
  both_sides_real_expt_lt1_lt_TCC1: OBLIGATION
    FORALL (a: real, lt1x: {r | r < 1}): a >= 0 OR lt1x > 0;

  % Subtype TCC generated (at line 80, column 42) for  a
      % expected type  {a | a >= 0 OR gt1x > 0}
  both_sides_real_expt_gt1_lt_TCC1: OBLIGATION
    FORALL (a: real, gt1x: {r | r > 1}): a >= 0 OR gt1x > 0;


body:
  %------------------------------------------------------------------------------
  % Generalized log function (without ln/exp)
  %
  %     Author: David Lester, Manchester University & NIA
  %
  %     Version 1.0            19/08/08   Initial version (DRL)
  %
  %------------------------------------------------------------------------------

  nn_log: THEORY

  BEGIN

    IMPORTING rational_props_aux,
              nn_root,
              nn_rational_expt,
              nnreal_expt

    a,b,x,y,z: VAR nnreal  
    q:       VAR nnrat
    px,py,pa,pb,
    delta,r,
    epsilon:   VAR posreal
    ne1x: VAR {r | r /= 1}
    gt1x,gt1y: VAR {r | r > 1}
    lt1x,lt1y: VAR {r | r < 1}

    log_gt1(gt1x):[{r | r>=1}->nnreal]
      = inverse[nnreal,{r | r>=1}](lambda x: nnreal_expt(gt1x,x))

    log_lt1(lt1x):[{r | r<=1}->nnreal]
      = inverse[nnreal,{r | r<=1}](lambda x: nnreal_expt(lt1x,x))

    nn_log(ne1x)(y:{r | ne1x>1 AND r>=1 OR ne1x<1 AND r<=1}):nnreal
      = IF ne1x>1 THEN log_gt1(ne1x)(y) ELSE log_lt1(ne1x)(y) ENDIF

    nn_log_expt: LEMMA nn_log(ne1x)(nnreal_expt(ne1x,y)) = y
    nn_expt_log: LEMMA FORALL (y:{r | ne1x>1 AND r>=1 OR ne1x<1 AND r<=1}):
                           nnreal_expt(ne1x,nn_log(ne1x)(y)) = y

    nn_log_plus: LEMMA FORALL (x,y:{r | ne1x>1 AND r>=1 OR ne1x<1 AND r<=1}):
                           nn_log(ne1x)(x*y) = nn_log(ne1x)(x) + nn_log(ne1x)(y)

    nn_log_1:    LEMMA nn_log(ne1x)(1)    = 0
    nn_log_ne1x: LEMMA nn_log(ne1x)(ne1x) = 1
    nn_log_gt1:  LEMMA nn_log(gt1x)(gt1y) > 1 IFF gt1y > gt1x

    nn_inv_base_log: LEMMA
       FORALL (y:{r | ne1x>1 AND r<=1 OR ne1x<1 AND r>=1}):
              nn_log(1/ne1x)(y) = nn_log(ne1x)(1/y)


    nn_log_increasing:  LEMMA 1 < x AND x < y =>
                                  nn_log(gt1x)(x) < nn_log(gt1x)(y)

  END nn_log

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 29, column 43) for  nnreal_expt(gt1x, x)
      % expected type  {r | r >= 1}
  log_gt1_TCC1: OBLIGATION
    FORALL (gt1x: {r | r > 1}, x):
      nnreal_expt(gt1x, x) > 0 AND nnreal_expt(gt1x, x) >= 1;

  % Subtype TCC generated (at line 32, column 43) for  nnreal_expt(lt1x, x)
      % expected type  {r | r <= 1}
  log_lt1_TCC1: OBLIGATION
    FORALL (lt1x: {r | r < 1}, x):
      nnreal_expt(lt1x, x) > 0 AND nnreal_expt(lt1x, x) <= 1;

  % Subtype TCC generated (at line 35, column 35) for  y
      % expected type  {r | r >= 1}
  nn_log_TCC1: OBLIGATION
    FORALL (ne1x: {r | r /= 1},
            y: {r | ne1x > 1 AND r >= 1 OR ne1x < 1 AND r <= 1}):
      ne1x > 1 IMPLIES y >= 1;

  % Subtype TCC generated (at line 35, column 57) for  y
      % expected type  {r | r <= 1}
  nn_log_TCC2: OBLIGATION
    FORALL (ne1x: {r | r /= 1},
            y: {r | ne1x > 1 AND r >= 1 OR ne1x < 1 AND r <= 1}):
      NOT ne1x > 1 IMPLIES y <= 1;

  % Subtype TCC generated (at line 35, column 51) for  ne1x
      % expected type  {r | r < 1}
  nn_log_TCC3: OBLIGATION
    FORALL (ne1x: {r | r /= 1},
            y: {r | ne1x > 1 AND r >= 1 OR ne1x < 1 AND r <= 1}):
      NOT ne1x > 1 IMPLIES ne1x < 1;

  % Subtype TCC generated (at line 37, column 34) for  nnreal_expt(ne1x, y)
      % expected type  {r | ne1x > 1 AND r >= 1 OR ne1x < 1 AND r <= 1}
  nn_log_expt_TCC1: OBLIGATION
    FORALL (ne1x: {r | r /= 1}, y: nnreal):
      nnreal_expt(ne1x, y) > 0 AND
       (ne1x > 1 AND nnreal_expt(ne1x, y) >= 1 OR
         ne1x < 1 AND nnreal_expt(ne1x, y) <= 1);

  % Subtype TCC generated (at line 42, column 38) for  x * y
      % expected type  {r | ne1x > 1 AND r >= 1 OR ne1x < 1 AND r <= 1}
  nn_log_plus_TCC1: OBLIGATION
    FORALL (ne1x: {r | r /= 1},
            x, y: {r | ne1x > 1 AND r >= 1 OR ne1x < 1 AND r <= 1}):
      ne1x > 1 AND x * y >= 1 OR ne1x < 1 AND x * y <= 1;

  % Subtype TCC generated (at line 44, column 34) for  1
      % expected type  {r | ne1x > 1 AND r >= 1 OR ne1x < 1 AND r <= 1}
  nn_log_1_TCC1: OBLIGATION
    FORALL (ne1x: {r | r /= 1}): ne1x > 1 AND 1 >= 1 OR ne1x < 1 AND 1 <= 1;

  % Subtype TCC generated (at line 45, column 34) for  ne1x
      % expected type  {r | ne1x > 1 AND r >= 1 OR ne1x < 1 AND r <= 1}
  nn_log_ne1x_TCC1: OBLIGATION
    FORALL (ne1x: {r | r /= 1}):
      ne1x > 1 AND ne1x >= 1 OR ne1x < 1 AND ne1x <= 1;

  % Subtype TCC generated (at line 46, column 34) for  gt1y
      % expected type  {r | gt1x > 1 AND r >= 1 OR gt1x < 1 AND r <= 1}
  nn_log_gt1_TCC1: OBLIGATION
    FORALL (gt1x, gt1y: {r | r > 1}):
      gt1x > 1 AND gt1y >= 1 OR gt1x < 1 AND gt1y <= 1;

  % Subtype TCC generated (at line 46, column 28) for  gt1x
      % expected type  ne1x: {r | r /= 1}
  nn_log_gt1_TCC2: OBLIGATION FORALL (gt1x: {r | r > 1}): gt1x /= 1;

  % Subtype TCC generated (at line 50, column 27) for  y
      % expected type  {r |
                     %          1 / ne1x > 1 AND r >= 1 OR
                     %           1 / ne1x < 1 AND r <= 1}
  nn_inv_base_log_TCC1: OBLIGATION
    FORALL (ne1x: {r | r /= 1},
            y: {r | ne1x > 1 AND r <= 1 OR ne1x < 1 AND r >= 1}):
      1 / ne1x > 1 AND y >= 1 OR 1 / ne1x < 1 AND y <= 1;

  % Subtype TCC generated (at line 50, column 19) for  1 / ne1x
      % expected type  ne1x: {r | r /= 1}
  nn_inv_base_log_TCC2: OBLIGATION
    FORALL (ne1x: {r | r /= 1},
            y: {r | ne1x > 1 AND r <= 1 OR ne1x < 1 AND r >= 1}):
      1 / ne1x /= 1;

  % Subtype TCC generated (at line 50, column 45) for  1 / y
      % expected type  {r | ne1x > 1 AND r >= 1 OR ne1x < 1 AND r <= 1}
  nn_inv_base_log_TCC3: OBLIGATION
    FORALL (ne1x: {r | r /= 1},
            y: {r | ne1x > 1 AND r <= 1 OR ne1x < 1 AND r >= 1}):
      ne1x > 1 AND 1 / y >= 1 OR ne1x < 1 AND 1 / y <= 1;

  % Subtype TCC generated (at line 54, column 45) for  x
      % expected type  {r | gt1x > 1 AND r >= 1 OR gt1x < 1 AND r <= 1}
  nn_log_increasing_TCC1: OBLIGATION
    FORALL (gt1x: {r | r > 1}, x, y: nnreal):
      x < y AND 1 < x IMPLIES
       x > 0 AND (gt1x > 1 AND x >= 1 OR gt1x < 1 AND x <= 1);

  % Subtype TCC generated (at line 54, column 63) for  y
      % expected type  {r | gt1x > 1 AND r >= 1 OR gt1x < 1 AND r <= 1}
  nn_log_increasing_TCC2: OBLIGATION
    FORALL (gt1x: {r | r > 1}, x, y: nnreal):
      x < y AND 1 < x IMPLIES
       y > 0 AND (gt1x > 1 AND y >= 1 OR gt1x < 1 AND y <= 1);


body:
  %------------------------------------------------------------------------------
  % Generalized log function (without ln/exp)
  %
  %     Author: David Lester, Manchester University & NIA
  %
  %     Version 1.0            19/08/08   Initial version (DRL)
  %
  % If we had ln to hand, then we could define
  %
  %   log(x)(y) = ln(y)/ln(x)
  %
  % Of course that would defeat the whole point of this library,
  % which is to be independent of the definition of ln/exp.
  % 
  %------------------------------------------------------------------------------

  log: THEORY

  BEGIN

    IMPORTING nn_log,
              real_expt

    a,b,r,x,y: VAR posreal
    z:         VAR real
    i:         VAR int
    ne1x,ne1y,ne1z: VAR {r | r /= 1}
    gt1x,gt1y,gt1z: VAR {r | r > 1}
    lt1x,lt1y,lt1z: VAR {r | r < 1}

    log(ne1x)(y):real
      = IF ne1x > 1 AND y >= 1 OR ne1x < 1 AND y <= 1
        THEN nn_log(ne1x)(y) ELSE -nn_log(ne1x)(1/y) ENDIF

    log(ne1x,y):real = log(ne1x)(y)

    log_expt: LEMMA log(ne1x)(ne1x^z) = z
    expt_log: LEMMA ne1x^log(ne1x)(y) = y

    log_1:        LEMMA log(ne1x)(1)    = 0
    log_ne1x:     LEMMA log(ne1x)(ne1x) = 1
    inv_base_log: LEMMA log(1/ne1x)(y)  = log(ne1x)(1/y)

    log_inv:  LEMMA log(ne1x)(1/y) = -log(ne1x)(y)
    log_mult: LEMMA log(ne1x)(x*y) = log(ne1x)(x) + log(ne1x)(y)
    log_div:  LEMMA log(ne1x)(x/y) = log(ne1x)(x) - log(ne1x)(y)
    log_xz:   LEMMA log(ne1x)(x^z) = z*log(ne1x)(x)

    log_increasing:  LEMMA x < y => log(gt1x)(x) < log(gt1x)(y)
    log_decreasing:  LEMMA x < y => log(lt1x)(x) > log(lt1x)(y)

    log_is_0: LEMMA log(ne1x)(y) = 0 IFF y = 1
    log_pos:  LEMMA log(ne1x)(y) > 0 IFF ne1x>1 AND y>1 OR ne1x<1 AND y<1
    log_neg:  LEMMA log(ne1x)(y) < 0 IFF ne1x>1 AND y<1 OR ne1x<1 AND y>1

    log_increasing1: LEMMA ((ne1z<1 AND (ne1x>1 OR  ne1y<1)) OR
                                (ne1z>1 AND  ne1x<1 AND ne1y>1)) AND
                               ne1x < ne1y =>
                               log(ne1x)(ne1z) < log(ne1y)(ne1z)
    log_decreasing1: LEMMA ((ne1z<1 AND  ne1x<1 AND  ne1y>1)   OR
                                (ne1z>1 AND (ne1x>1 OR   ne1y<1))) AND
                               ne1x < ne1y =>
                               log(ne1x)(ne1z) > log(ne1y)(ne1z)

    both_sides_log_gt1_lt: LEMMA
      log(gt1x)(x) <  log(gt1x)(y) IFF x <  y
    both_sides_log_gt1_le: LEMMA
      log(gt1x)(x) <= log(gt1x)(y) IFF x <= y
    both_sides_log_gt1_gt: LEMMA
      log(gt1x)(x) >  log(gt1x)(y) IFF x >  y
    both_sides_log_gt1_ge: LEMMA
      log(gt1x)(x) >= log(gt1x)(y) IFF x >= y

    both_sides_log_lt1_lt: LEMMA
      log(lt1x)(x) <  log(lt1x)(y) IFF y <  x
    both_sides_log_lt1_le: LEMMA
      log(lt1x)(x) <= log(lt1x)(y) IFF y <= x
    both_sides_log_lt1_gt: LEMMA
      log(lt1x)(x) >  log(lt1x)(y) IFF y >  x
    both_sides_log_lt1_ge: LEMMA
      log(lt1x)(x) >= log(lt1x)(y) IFF y >= x

    both_sides_log: LEMMA log(ne1x)(x) = log(ne1x)(y) IFF x = y

  END log

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 33, column 46) for  1 / y
      % expected type  {r | ne1x > 1 AND r >= 1 OR ne1x < 1 AND r <= 1}
  log_TCC1: OBLIGATION
    FORALL (ne1x: {r | r /= 1}, y: posreal):
      NOT (ne1x > 1 AND y >= 1) AND NOT (ne1x < 1 AND y <= 1) IMPLIES
       ne1x > 1 AND 1 / y >= 1 OR ne1x < 1 AND 1 / y <= 1;

  % Subtype TCC generated (at line 37, column 33) for  z
      % expected type  {a | a >= 0 OR ne1x > 0}
  log_expt_TCC1: OBLIGATION
    FORALL (ne1x: {r | r /= 1}, z: real): z >= 0 OR ne1x > 0;

  % Subtype TCC generated (at line 37, column 28) for  ne1x ^ z
      % expected type  posreal
  log_expt_TCC2: OBLIGATION
    FORALL (ne1x: {r | r /= 1}, z: real): ne1x ^ z > 0;

  % Subtype TCC generated (at line 38, column 23) for  log(ne1x)(y)
      % expected type  {a | a >= 0 OR ne1x > 0}
  expt_log_TCC1: OBLIGATION
    FORALL (ne1x: {r | r /= 1}, y: posreal): log(ne1x)(y) >= 0 OR ne1x > 0;

  % Subtype TCC generated (at line 42, column 26) for  1 / ne1x
      % expected type  {r | r /= 1}
  inv_base_log_TCC1: OBLIGATION FORALL (ne1x: {r | r /= 1}): 1 / ne1x /= 1;

  % Subtype TCC generated (at line 47, column 30) for  z
      % expected type  {a | a >= 0 OR x > 0}
  log_xz_TCC1: OBLIGATION FORALL (x: posreal, z: real): z >= 0 OR x > 0;

  % Subtype TCC generated (at line 47, column 28) for  x ^ z
      % expected type  posreal
  log_xz_TCC2: OBLIGATION FORALL (x: posreal, z: real): x ^ z > 0;

  % Subtype TCC generated (at line 49, column 38) for  gt1x
      % expected type  {r | r /= 1}
  log_increasing_TCC1: OBLIGATION
    FORALL (gt1x: {r | r > 1}, x, y: posreal): x < y IMPLIES gt1x /= 1;

  % Subtype TCC generated (at line 50, column 38) for  lt1x
      % expected type  {r | r /= 1}
  log_decreasing_TCC1: OBLIGATION
    FORALL (lt1x: {r | r < 1}, x, y: posreal): x < y IMPLIES lt1x /= 1;

  % Subtype TCC generated (at line 66, column 8) for  gt1x
      % expected type  {r | r /= 1}
  both_sides_log_gt1_lt_TCC1: OBLIGATION
    FORALL (gt1x: {r | r > 1}): gt1x /= 1;

  % Subtype TCC generated (at line 75, column 8) for  lt1x
      % expected type  {r | r /= 1}
  both_sides_log_lt1_lt_TCC1: OBLIGATION
    FORALL (lt1x: {r | r < 1}): lt1x /= 1;


body:
  % 
  % David Lester, Manchester University
  % 10/10/08
  %
  % Linking log and ^ to exp and ln.


  ln_exp_def: THEORY

  BEGIN

    IMPORTING log,
              real_expt,
              lnexp_fnd@ln_exp

    i:    VAR int
    n:    VAR nat
    q:    VAR nnrat
    pn:   VAR posnat
    x:    VAR real
    z:    VAR nnreal
    a,r,y: VAR posreal
    ne1x: VAR {r | r /= 1}

    expt_exp:    LEMMA expt(y,n) = exp(n*ln(y))

    nn_root_def: LEMMA nn_root(z,pn) = IF z = 0 THEN 0 ELSE exp(ln(z)/pn) ENDIF

    nn_rational_expt_def: LEMMA nn_rational_expt(y,q) = exp(q*ln(y))

    nnreal_expt_def:      LEMMA nnreal_expt(y,z) = exp(z*ln(y))

    real_expt_def:        LEMMA y^x = exp(x*ln(y))

    nn_log_def: LEMMA r > 1 AND y >= 1 OR r < 1 AND y <= 1 =>
                      nn_log(r)(y) = ln(y)/ln(r)

    log_def:    LEMMA log(ne1x,y) = ln(y)/ln(ne1x)

    IMPORTING analysis@continuous_functions,
              analysis@derivatives

    log_continuous: LEMMA continuous?[posreal](log(ne1x))
    log_derivable:  LEMMA derivable?[posreal](log(ne1x)) AND
                          deriv[posreal](log(ne1x)) = (LAMBDA y: 1/(ln(ne1x)*y))

    real_expt_continuous: LEMMA continuous?[posreal](lambda y: y^x)
    real_expt_derivable:  LEMMA derivable?[posreal](lambda y: y^x) AND
                                deriv[posreal](lambda y: y^x)
                                     = (lambda y: x*y^(x-1))


  END ln_exp_def

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 27, column 65) for  z
      % expected type  posreal
  nn_root_def_TCC1: OBLIGATION FORALL (z: nnreal): NOT z = 0 IMPLIES z > 0;

  % Subtype TCC generated (at line 33, column 32) for  x
      % expected type  {a | a >= 0 OR y > 0}
  real_expt_def_TCC1: OBLIGATION
    FORALL (x: real, y: posreal): x >= 0 OR y > 0;

  % Subtype TCC generated (at line 36, column 27) for  r
      % expected type  ne1x: {r | r /= 1}
  nn_log_def_TCC1: OBLIGATION
    FORALL (r, y: posreal):
      r > 1 AND y >= 1 OR r < 1 AND y <= 1 IMPLIES r /= 1;

  % Subtype TCC generated (at line 36, column 41) for  ln(r)
      % expected type  nznum
  nn_log_def_TCC2: OBLIGATION
    FORALL (r, y: posreal):
      r > 1 AND y >= 1 OR r < 1 AND y <= 1 IMPLIES ln(r) /= 0;

  % Subtype TCC generated (at line 38, column 40) for  ln(ne1x)
      % expected type  nznum
  log_def_TCC1: OBLIGATION FORALL (ne1x: {r | r /= 1}): ln(ne1x) /= 0;

  % Assuming TCC generated (at line 24, column 4) for
      % analysis@derivatives[posreal]
      % generated from assumption derivatives.deriv_domain
  log_derivable_TCC1: OBLIGATION deriv_domain?[posreal];

  % Assuming TCC generated (at line 26, column 4) for
      % analysis@derivatives[posreal]
      % generated from assumption derivatives.not_one_element
  log_derivable_TCC2: OBLIGATION not_one_element?[posreal];

  % Subtype TCC generated (at line 45, column 66) for  (ln(ne1x) * y)
      % expected type  nznum
  log_derivable_TCC3: OBLIGATION
    FORALL (ne1x: {r | r /= 1}):
      derivable?[posreal](log(ne1x)) IMPLIES
       (FORALL (y): (ln(ne1x) * y) /= 0);

  % Subtype TCC generated (at line 50, column 53) for  (x - 1)
      % expected type  {a | a >= 0 OR y > 0}
  real_expt_derivable_TCC1: OBLIGATION
    FORALL (x: real):
      derivable?[posreal](LAMBDA y: y ^ x) IMPLIES
       (FORALL (y1): (x - 1) >= 0 OR y1 > 0);


body:
  %------------------------------------------------------------------------------
  % Exponentials of functions
  %
  %     Author: David Lester, Manchester University & NIA
  %
  %     Version 1.0            15/09/08   Initial version (DRL)
  %
  % Note carefully that f^a is actually |f|^a. If you want $f^(1/3)$ to
  % be $\root[3]{f(x)}$, write it as $sign(f) * f^(1/3)$.
  %
  %------------------------------------------------------------------------------

  real_fun_power[T:TYPE]: THEORY

  BEGIN

    IMPORTING reals@sign,
              real_expt

    f: VAR [T->real]
    g: VAR [T->nnreal]
    a: VAR posreal
    x: VAR T
    n: VAR nat

    sign(f):  [T->real]   = lambda x: sign(f(x));
    ^(g,a):   [T->nnreal] = lambda x: g(x)^a;
    expt(f,n):[T->real]   = lambda x: expt(f(x),n)

  END real_fun_power

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 27, column 41) for  a
      % expected type  {a | a >= 0 OR g(x) > 0}
  caret_TCC1: OBLIGATION
    FORALL (g: [T -> nnreal], a: posreal, x): a >= 0 OR g(x) > 0;


body:
  top: THEORY

  BEGIN

    IMPORTING continuous_functions_aux,
              probability_measure,
              probability_space,
              conditional,
              expectation
  %            correlation

  END top


body:
  continuous_functions_aux[T : TYPE FROM real] : THEORY

  BEGIN

    f             : VAR [T -> real]
    x, x0         : VAR T
    n:              VAR nat
    epsilon, delta: VAR posreal

    IMPORTING analysis@continuous_functions[T],
              analysis@convergence_ops

    right_continuous?(f,x0): bool
      = FORALL epsilon: EXISTS delta: FORALL x: x0 <= x AND x - x0 < delta 
                               IMPLIES abs(f(x) - f(x0)) < epsilon

    left_continuous?(f,x0): bool
      = FORALL epsilon: EXISTS delta: FORALL x: x <= x0 AND x0 - x < delta 
                               IMPLIES abs(f(x) - f(x0)) < epsilon


    right_continuous?(f): bool = FORALL x0 : right_continuous?(f, x0)
    left_continuous?(f): bool  = FORALL x0 : left_continuous?(f, x0)

    continuous_lr_def: LEMMA continuous?(f) IFF
                             right_continuous?(f) AND left_continuous?(f)

  END continuous_functions_aux


body:
  probability_measure[T:TYPE+,(IMPORTING measure_integration@subset_algebra_def[T])
                      S:sigma_algebra]: THEORY

  BEGIN


    IMPORTING measure_integration@sigma_algebra[T,S],
              measure_integration@measure_def[T,S],
              %% ..... @fun_preds[T,real],
              reals@real_fun_ops[T],
              structures@fun_preds_partial[nat,set[T],reals.<=,subset?[T]],
              metric_space@real_topology,
              topology@basis[real],
              %% metric_space@borel[real,metric_induced_topology],
              measure_integration@hausdorff_borel[real,metric_induced_topology],
              measure_integration@real_borel,
              measure_integration@measure_space_def[T,S],
              measure_integration@finite_measure

    probability:   TYPE+ = {x:nnreal  | x <= 1} CONTAINING 1
    nzprobability: TYPE+ = {x:posreal | x <= 1} CONTAINING 1

    nzprobability_is_probability: JUDGEMENT nzprobability SUBTYPE_OF probability

    probability_measure_full?(P:[(S)->probability]):bool = P(fullset[T])= 1

    probability_measure?(P:[(S)->probability]):bool
      = probability_measure_full?(P) AND finite_measure?(P)

    trivial_probability_measure(A:(S)):probability
      = IF member(choose(fullset[T]),A) THEN 1 ELSE 0 ENDIF

    probability_measure: TYPE+ = (probability_measure?)
                                           CONTAINING trivial_probability_measure

    probability_measure_is_finite_measure:
                         JUDGEMENT probability_measure SUBTYPE_OF finite_measure

    random_variable?(f:[T->real]):bool = measurable_function?(f)

    random_variable: TYPE+ = (measurable_function?) CONTAINING (lambda (x:T): 0)

    random_variable_is_measurable_function:
                         JUDGEMENT random_variable SUBTYPE_OF measurable_function

    P:   VAR probability_measure
    A,B: VAR (S)
    SS:  VAR disjoint_indexed_measurable
    X:   VAR sequence[(S)]
    Y:   VAR random_variable
    x:   VAR real
    t:   VAR T

    P_fullset:      LEMMA P(fullset)       = 1
    P_convergence:  LEMMA convergence(series(P o SS), P(IUnion(SS)))
    P_emptyset:     LEMMA P(emptyset)      = 0
    P_disjointunion:LEMMA disjoint?(A,B) => P(union(A,B)) = P(A) + P(B)
    P_complement:   LEMMA P(complement(A)) = 1 - P(A)
    P_union:        LEMMA P(union(A,B))    = P(A) + P(B) - P(intersection(A,B))
    P_intersection: LEMMA P(intersection(A,B))= P(A) + P(B) - P(union(A,B))
    P_difference:   LEMMA P(difference(A,B))  = P(A) - P(B) + P(difference(B,A))
    P_subset:       LEMMA subset?(A,B)   => P(B) = P(A) + P(difference(B,A))
    P_subset_le:    LEMMA subset?(A,B)   => P(A) <= P(B)
    P_IUnion:       LEMMA increasing?(X) => convergence(P o X,P(IUnion(X)))
    P_IIntersection:LEMMA decreasing?(X) => convergence(P o X,P(IIntersection(X)))

    P0_intersection:LEMMA P(A) = 0 => P(intersection(A,B)) = 0
    P0_union:       LEMMA P(A) = 0 => P(union(A,B))        = P(B)
    P1_intersection:LEMMA P(A) = 1 => P(intersection(A,B)) = P(B)
    P1_union:       LEMMA P(A) = 1 => P(union(A,B))        = 1

    measure_to_df(P)(Y)(x):probability = P({t | Y(t) <= x})

  END probability_measure

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 31, column 23) for  fullset[T]
      % expected type  p: (nonempty?[T])
  trivial_probability_measure_TCC1: OBLIGATION
    FORALL (A: (S)): nonempty?[T](fullset[T]);

  % Subtype TCC generated (at line 34, column 52) for
      % trivial_probability_measure
      % expected type  probability_measure
  probability_measure_TCC1: OBLIGATION
    probability_measure?(trivial_probability_measure);

  % Judgement subtype TCC generated (at line 37, column 33) for  x
      % expected type  finite_measure[T, S]
  probability_measure_is_finite_measure: OBLIGATION
    FORALL (x: probability_measure): finite_measure?[T, S](x);

  % Subtype TCC generated (at line 41, column 62) for  (LAMBDA (x: T): 0)
      % expected type  random_variable
  random_variable_TCC1: OBLIGATION
    measurable_function?[T, S]((LAMBDA (x: T): 0));

  % Subtype TCC generated (at line 72, column 41) for  {t | Y(t) <= x}
      % expected type  (S)
  measure_to_df_TCC1: OBLIGATION
    FORALL (Y: random_variable, x: real): S({t | Y(t) <= x});


body:
  probability_space[T:TYPE+,(IMPORTING measure_integration@subset_algebra_def[T])
                    S:sigma_algebra,   (IMPORTING probability_measure[T,S])
                    P:probability_measure]: THEORY

  BEGIN

     IMPORTING measure_integration@sigma_algebra[T,S],
               probability_measure[T,S],
               continuous_functions_aux[real],
               measure_integration@measure_space[T,S],
               measure_integration@measure_props[T,S,to_measure(P)],
               measure_integration@real_borel

     limit: MACRO [(convergence_sequences.convergent?)->real]
                                                    = convergence_sequences.limit

     phi,g,h: VAR borel_function
     B1,B2:   VAR borel
     A,B: VAR (S)
     x,y: VAR real
     n0z: VAR nzreal
     t:   VAR T
     n:   VAR nat
     X,Y: VAR random_variable
     XS:  VAR [nat->random_variable]

     null?(A)         :bool = P(A) = 0
     non_null?(A)     :bool = NOT null?(A)
     independent?(A,B):bool = P(intersection(A,B)) = P(A) * P(B)

  % Note carefully that the above DOES NOT say: ... = 0

     zero: random_variable = (LAMBDA t: 0)
     one:  random_variable = (LAMBDA t: 1)

     ; % needed for syntax purposes!

     <=(X,x):(S) = {t | X(t) <= x};
     <(x,X): (S) = {t | X(t) >  x};
     =(X,x): (S) = {t | X(t) =  x};
     <(X,x): (S) = {t | X(t) <  x};
     <=(x,X):(S) = {t | X(t) >= x};
     /=(X,x):(S) = {t | X(t) /= x};

     complement_le1: LEMMA complement(X <= x) = (x <  X)
     complement_lt1: LEMMA complement(x <  X) = (X <= x)
     complement_eq : LEMMA complement(X =  x) = (X /= x)
     complement_lt2: LEMMA complement(X <  x) = (x <= X)
     complement_le2: LEMMA complement(x <= X) = (X <  x)
     complement_ne:  LEMMA complement(X /= x) = (X =  x)

     ; % needed for syntax purposes!

     +(X,x)  :random_variable = (LAMBDA t: X(t) + x);
     +(x,X)  :random_variable = (LAMBDA t: x + X(t));
     -(X,x)  :random_variable = (LAMBDA t: X(t) - x);
     -(x,X)  :random_variable = (LAMBDA t: x - X(t));
     /(X,n0z):random_variable = (LAMBDA t: X(t)/n0z);

     independent?(X,Y):bool
       = FORALL B1,B2: independent?(inverse_image(X,B1),inverse_image(Y,B2))

     borel_comp_rv_is_rv: JUDGEMENT o(phi,X) HAS_TYPE random_variable

     borel_independence: LEMMA independent?(X,Y) => independent?(g o X, h o Y)

     partial_sum_is_random_variable:
       LEMMA random_variable?(LAMBDA t: sigma(0,n,LAMBDA n: XS(n)(t)))

     distribution_function?(F:[real->probability]):bool
                                         = EXISTS X: FORALL x: F(x) = P(X <= x)

     distribution_function: TYPE+ = (distribution_function?) CONTAINING
                                        (LAMBDA x: IF x < 0 THEN 0 ELSE 1 ENDIF)

     distribution_function(X)(x):probability = P(X <= x)

     convergence_in_distribution?(XS,X):bool
       = FORALL x: continuous?(distribution_function(X),x) IMPLIES
                    convergence((LAMBDA n: distribution_function(XS(n))(x)),
                                           distribution_function(X)(x))
  % Lemma 2.1.11 (G&S)

     invert_distribution:   LEMMA LET F = distribution_function(X) IN
                                  P(x < X) = 1 - F(x)
     interval_distribution: LEMMA LET F = distribution_function(X) IN
                                  x <= y IMPLIES 
                                  P(intersection(x < X, X <= y)) = F(y) - F(x)
     limit_distribution:    LEMMA LET F = distribution_function(X) IN
                                  P(X = x) = F(x) - limit(LAMBDA n: F(x-1/(n+1)))

  % Lemma 2.1.6 in G&S

     F: VAR distribution_function

     distribution_0:                LEMMA convergence(F o (lambda (n:nat): -n),0)
     distribution_1:                LEMMA convergence(F,1)
     distribution_increasing:       LEMMA increasing?[real](F)
     distribution_right_continuous: LEMMA right_continuous?(F)

       
  END probability_space

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 33, column 28) for  (LAMBDA t: 0)
      % expected type  random_variable[T, S]
  zero_TCC1: OBLIGATION measurable_function?[T, S]((LAMBDA t: 0));

  % Subtype TCC generated (at line 34, column 28) for  (LAMBDA t: 1)
      % expected type  random_variable[T, S]
  one_TCC1: OBLIGATION measurable_function?[T, S]((LAMBDA t: 1));

  % Subtype TCC generated (at line 38, column 17) for  {t | X(t) <= x}
      % expected type  (S)
  lesseqp_TCC1: OBLIGATION
    FORALL (X: random_variable[T, S], x: real): S({t | X(t) <= x});

  % Subtype TCC generated (at line 39, column 17) for  {t | X(t) > x}
      % expected type  (S)
  lessp_TCC1: OBLIGATION
    FORALL (x: real, X: random_variable[T, S]): S({t | X(t) > x});

  % Subtype TCC generated (at line 40, column 17) for  {t | X(t) = x}
      % expected type  (S)
  equal_TCC1: OBLIGATION
    FORALL (X: random_variable[T, S], x: real): S({t | X(t) = x});

  % Subtype TCC generated (at line 41, column 17) for  {t | X(t) < x}
      % expected type  (S)
  lessp_TCC2: OBLIGATION
    FORALL (X: random_variable[T, S], x: real): S({t | X(t) < x});

  % Subtype TCC generated (at line 42, column 17) for  {t | X(t) >= x}
      % expected type  (S)
  lesseqp_TCC2: OBLIGATION
    FORALL (x: real, X: random_variable[T, S]): S({t | X(t) >= x});

  % Subtype TCC generated (at line 43, column 17) for  {t | X(t) /= x}
      % expected type  (S)
  notequal_TCC1: OBLIGATION
    FORALL (X: random_variable[T, S], x: real): S({t | X(t) /= x});

  % Subtype TCC generated (at line 54, column 31) for  (LAMBDA t: X(t) + x)
      % expected type  random_variable[T, S]
  plus_TCC1: OBLIGATION
    FORALL (X: random_variable[T, S], x: real):
      measurable_function?[T, S](LAMBDA t: X(t) + x);

  % Subtype TCC generated (at line 55, column 31) for  (LAMBDA t: x + X(t))
      % expected type  random_variable[T, S]
  plus_TCC2: OBLIGATION
    FORALL (x: real, X: random_variable[T, S]):
      measurable_function?[T, S](LAMBDA t: x + X(t));

  % Subtype TCC generated (at line 56, column 31) for  (LAMBDA t: X(t) - x)
      % expected type  random_variable[T, S]
  difference_TCC1: OBLIGATION
    FORALL (X: random_variable[T, S], x: real):
      measurable_function?[T, S](LAMBDA t: X(t) - x);

  % Subtype TCC generated (at line 57, column 31) for  (LAMBDA t: x - X(t))
      % expected type  random_variable[T, S]
  difference_TCC2: OBLIGATION
    FORALL (x: real, X: random_variable[T, S]):
      measurable_function?[T, S](LAMBDA t: x - X(t));

  % Subtype TCC generated (at line 58, column 31) for  (LAMBDA t: X(t) / n0z)
      % expected type  random_variable[T, S]
  divide_TCC1: OBLIGATION
    FORALL (X: random_variable[T, S], n0z: nzreal):
      measurable_function?[T, S](LAMBDA t: X(t) / n0z);

  % Subtype TCC generated (at line 61, column 34) for  inverse_image(X, B1)
      % expected type  (S)
  independent?_TCC1: OBLIGATION
    FORALL (X: random_variable[T, S], B1): S(inverse_image[T, real](X, B1));

  % Subtype TCC generated (at line 68, column 46) for  n
      % expected type  T_high[nat]
  partial_sum_is_random_variable_TCC1: OBLIGATION
    FORALL (n: nat): n >= 0 OR (EXISTS (j: nat): n <= j);

  % Subtype TCC generated (at line 74, column 39) for
      % (LAMBDA x: IF x < 0 THEN 0 ELSE 1 ENDIF)
      % expected type  distribution_function
  distribution_function_TCC1: OBLIGATION
    distribution_function?((LAMBDA x: IF x < 0 THEN 0 ELSE 1 ENDIF));

  % Subtype TCC generated (at line 90, column 56) for
      % LAMBDA n: F(x - 1 / (n + 1))
      % expected type  (convergent?)
  limit_distribution_TCC1: OBLIGATION
    FORALL (X: random_variable[T, S], x: real,
            F: [real -> probability[T, S]]):
      F = distribution_function(X) IMPLIES
       convergent?(LAMBDA n: F(x - 1 / (n + 1)));


body:
  expectation[T:TYPE+,      (IMPORTING measure_integration@subset_algebra_def[T])
              S:sigma_algebra,   (IMPORTING probability_measure[T,S])
              P:probability_measure]: THEORY

  BEGIN

    IMPORTING probability_measure[T,S],
              measure_integration@measure_def[T,S],
              measure_integration@integral[T,S,to_measure(P)],
              measure_integration@indefinite_integral[T,S,to_measure(P)], % Proof only
              probability_space[T,S,P]

    X,Y: VAR integrable
    x,c: VAR real
    t:   VAR T
    A:   VAR (S)

    E(X):real = integral(X)

    E_zero:   LEMMA E(zero)   = 0
    E_one:    LEMMA E(one)    = 1
    E_phi:    LEMMA E(phi(A)) = P(A)
    E_add:    LEMMA E(X+Y)    = E(X) + E(Y)
    E_scal:   LEMMA E(c*X)    = c*E(X)
    E_opp:    LEMMA E(-X)     = -E(X)
    E_diff:   LEMMA E(X-Y)    = E(X) - E(Y)
    E_nonneg: LEMMA (FORALL t: X(t) >= 0) => E(X) >= 0

    px: VAR posreal

    markov_inequality: THEOREM P(px <= abs(X)) <= E(abs(X))/px

    markov_inequality_alt: LEMMA x*P(x <= abs(X)) <= E(abs(X))

  END expectation

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 20, column 20) for  zero
      % expected type  integrable[T, S, to_measure(P)]
  E_zero_TCC1: OBLIGATION integrable?[T, S, to_measure(P)](zero[T, S, P]);

  % Subtype TCC generated (at line 21, column 20) for  one
      % expected type  integrable[T, S, to_measure(P)]
  E_one_TCC1: OBLIGATION integrable?[T, S, to_measure(P)](one[T, S, P]);

  % Subtype TCC generated (at line 22, column 20) for  phi(A)
      % expected type  integrable[T, S, to_measure(P)]
  E_phi_TCC1: OBLIGATION
    FORALL (A: (S)): integrable?[T, S, to_measure(P)](phi[T, S](A));

  % Subtype TCC generated (at line 31, column 37) for  abs(X)
      % expected type  random_variable[T, S]
  markov_inequality_TCC1: OBLIGATION
    FORALL (X: integrable[T, S, to_measure(P)]):
      measurable_function?[T, S](abs[T](X));


body:
  conditional[T:TYPE+,                (IMPORTING measure_integration@subset_algebra_def[T])
              S:sigma_algebra,        (IMPORTING probability_measure[T,S])
              P:probability_measure]: THEORY

  BEGIN

     IMPORTING probability_measure[T,S],
               measure_integration@sigma_algebra[T,S]

     A,B:   VAR (S)
     n,i,j: VAR nat
     AA,BB: VAR disjoint_indexed_measurable

     null?(A):bool = P(A) = 0

     P(A,B):probability = IF null?(B) THEN 0 ELSE P(intersection(A,B))/P(B) ENDIF

     conditional_complement: LEMMA
                    P(A,B) * P(B) + P(A,complement(B)) * P(complement(B)) = P(A)

     conditional_partition: LEMMA
             Union(image(BB,fullset[below[n+1]])) = fullset[T] IMPLIES
             P(A) = sigma(0,n, LAMBDA i: P(A, BB(i)) * P(BB(i)))

     bayes_theorem: THEOREM
             NOT null?(B) AND
             Union(image(AA,fullset[below[n+1]])) = fullset[T] IMPLIES
             P(AA(j),B) = P(B,AA(j))*P(AA(j))/
                          sigma(0,n, LAMBDA i: P(B, AA(i)) * P(AA(i)))

  END conditional

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 16, column 69) for  P(B)
      % expected type  nznum
  P_TCC1: OBLIGATION FORALL (A: (S), B: (S)): NOT null?(B) IMPLIES P(B) /= 0;

  % Subtype TCC generated (at line 16, column 48) for
      % P(intersection(A, B)) / P(B)
      % expected type  probability[T, S]
  P_TCC2: OBLIGATION
    FORALL (A: (S), B: (S)):
      NOT null?(B) IMPLIES
       P(intersection[T](A, B)) / P(B) >= 0 AND
        P(intersection[T](A, B)) / P(B) <= 1;

  % Subtype TCC generated (at line 23, column 26) for  n
      % expected type  T_high[nat]
  conditional_partition_TCC1: OBLIGATION
    FORALL (BB: disjoint_indexed_measurable[T, S], n: nat):
      Union(extend[setof[T], (S), bool, FALSE]
                (image(BB,
                       extend[nat, below[1 + n], bool, FALSE]
                           (fullset[below[1 + n]]))))
       = fullset[T]
       IMPLIES n >= 0 OR (EXISTS (j: nat): n <= j);

  % Subtype TCC generated (at line 29, column 24) for
      % sigma(0, n, LAMBDA i: P(B, AA(i)) * P(AA(i)))
      % expected type  nznum
  bayes_theorem_TCC1: OBLIGATION
    FORALL (AA: disjoint_indexed_measurable[T, S], B: (S), n: nat):
      Union(extend[setof[T], (S), bool, FALSE]
                (image(AA,
                       extend[nat, below[1 + n], bool, FALSE]
                           (fullset[below[1 + n]]))))
       = fullset[T]
       AND NOT null?(B)
       IMPLIES sigma[nat](0, n, LAMBDA i: P(B, AA(i)) * P(AA(i))) /= 0;


body:
  %------------------------------------------------------------------------------
  % Top for Scott Topology
  %
  % All references are to BA Davey and HA Priestly "Introduction to Lattices and
  % Orders", CUP, 1990.
  %
  % This library defines the Scott Topology, and shows that continuous functions
  % are increasing and lub-preserving; and -- under pointwise-ordering -- also
  % form a Scott Topology.
  %
  % The main reason Computer Scientists are interested is that it constitutes a
  % general foundation on which to build the fixpoint theory needed for the
  % semantics of loops or recursion.
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            25/12/07  Initial Version
  %------------------------------------------------------------------------------

  top: THEORY

  BEGIN

    IMPORTING
      partial_function_props,       % Easy-to-use partial function properties
      scott,                        % Definition of Scott Topology
      scott_continuity,             % Definition of Continuity
      pointwise_orders_aux,         % Extras for continuous pointwise orders
      scott_identity_continuity,    % Identity is scott continuous
      scott_composition_continuity, % Composition is scott continuous
      fixpoints,                    % Definition of Fixpoints
      admissible,                   % Fixpoint induction
      dual_fixpoints,               % Fixpoint Induction over two types
      scott_product

  % Extras for orders library %% INTEGRATED %%
  %
  %     bounded_orders_aux,     % Extras for orders@bounded_orders
  %     ordered_subset_aux,     % Extras for orders@ordered_subset
  %
  % New Theory files for orders library  %% MOVED %%
  %
  %     lift_props,             % Extras for the lift datatype
  %     directed_orders,        % New theories for orders library
  %     bounded_order_props,    % Properties of bounded orders
  %     directed_order_props,   % Properties of directed orders
  %     partial_order_props,    % Properties of partial orders
  %     partial_order_lift
  %     lifted_orders,          % Induced properties of lifted orders
  %     sum_orders,             % Induced properties of union orders
  %     product_orders          % Induced properties of product orders

  END top


body:
  %------------------------------------------------------------------------------
  % Scott Topology
  %
  % All references are to BA Davey and HA Priestly "Introduction to Lattices and
  % Orders", CUP, 1990
  %
  % Notice that this is a T0 topology, and not Hausdorff (unless the order is
  % equality).
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            25/12/07  Initial Version
  %------------------------------------------------------------------------------

  scott[T:TYPE, (IMPORTING orders@directed_orders[T])
        <=:(directed_complete_partial_order?[T])]:THEORY

  BEGIN

    IMPORTING topology@topology_def[T],
              orders@directed_order_props[T,<=]

    x,y: VAR T
    L:   VAR lower_set
    LS:  VAR lower_sets
    D:   VAR directed

    scott_closed_sets:setofsets[T]
      = {L | FORALL D: subset?(D,L) IMPLIES member(lub(D),L)}

    scott_open_sets:setofsets[T] = Complement(scott_closed_sets)

    down_is_closed:     LEMMA member(down(x),scott_closed_sets)

    scott_empty:        LEMMA member(emptyset, scott_closed_sets)

    scott_full:         LEMMA member(fullset,  scott_closed_sets)

    scott_union:        LEMMA FORALL (A,B:(scott_closed_sets)):
                                member(union(A,B), scott_closed_sets)

    scott_Intersection: LEMMA subset?(LS,scott_closed_sets) IMPLIES
                                member(Intersection(LS), scott_closed_sets)

    scott_topology:     LEMMA topology?(scott_open_sets)

    scott_open_sets_is_topology: JUDGEMENT scott_open_sets HAS_TYPE topology

    IMPORTING topology@topology[T,scott_open_sets]

    A: VAR open_set

    closed_is_lower:   JUDGEMENT (closed?) SUBTYPE_OF lower_set
    open_is_upper:     JUDGEMENT (open?)   SUBTYPE_OF upper_set

    closure_is_down:   LEMMA Cl(singleton(x)) = down(x)
    order_iff_closure: LEMMA x <= y IFF member(x,Cl(singleton(y)))
    order_iff_subset:  LEMMA x <= y IFF FORALL A: member(x,A) IMPLIES member(y,A)
    scott_is_T0:       LEMMA T0_space?(scott_open_sets)

    scott_hausdorff:   LEMMA
                 hausdorff_space?(scott_open_sets) IFF trivial_partial_order?(<=)

  END scott

addendum:
  %%% ================ Addendum: generated declarations ================

  % Judgement subtype TCC generated (at line 47, column 41) for
      % scott_open_sets
      % expected type  topology[T]
  scott_open_sets_is_topology: OBLIGATION topology?[T](scott_open_sets);

  % Judgement subtype TCC generated (at line 53, column 31) for  x
      % expected type  lower_set[T, <=]
  closed_is_lower: OBLIGATION FORALL (x: (closed?)): lower_set?[T, <=](x);

  % Judgement subtype TCC generated (at line 54, column 31) for  x
      % expected type  upper_set[T, <=]
  open_is_upper: OBLIGATION FORALL (x: (open?)): upper_set?[T, <=](x);


body:
  scott_product[T1,T2:TYPE, (IMPORTING orders@product_orders)
                 le1:(directed_complete_partial_order?[T1]),
                 le2:(directed_complete_partial_order?[T2])]: THEORY

  BEGIN

    x,y: VAR [T1,T2]

    product_order(le1:(partial_order?[T1]),
                  le2:(partial_order?[T2])):
                                    (partial_order?[[T1,T2]])
      = (LAMBDA x,y: le1(x`1,y`1) & le2(x`2,y`2))

    IMPORTING scott[[T1,T2],(product_order(le1,le2))]

  END scott_product

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 12, column 7) for
      % (LAMBDA x, y: le1(x`1, y`1) & le2(x`2, y`2))
      % expected type  (partial_order?[[T1, T2]])
  product_order_TCC1: OBLIGATION
    FORALL (le1: (partial_order?[T1]), le2: (partial_order?[T2])):
      partial_order?[[T1, T2]]((LAMBDA x, y: le1(x`1, y`1) & le2(x`2, y`2)));

  % Subtype TCC generated (at line 14, column 41) for  le1
      % expected type  (partial_order?[T1])
  IMP_scott_TCC1: OBLIGATION partial_order?[T1](le1);

  % Subtype TCC generated (at line 14, column 45) for  le2
      % expected type  (partial_order?[T2])
  IMP_scott_TCC2: OBLIGATION partial_order?[T2](le2);

  % Subtype TCC generated (at line 14, column 27) for
      % (product_order(le1, le2))
      % expected type  (directed_complete_partial_order?[[T1, T2]])
  IMP_scott_TCC3: OBLIGATION
    directed_complete_partial_order?[[T1, T2]]((product_order(le1, le2)));


body:
  fun_preds_partial[T1,T2:TYPE,le1:(partial_order?[T1]),
                               le2:(partial_order?[T2])]: THEORY

    BEGIN

    f,g,h: VAR [T1->T2]
    x,y:   VAR T1
    a,b:   VAR T2

    lt1(x,y)  : MACRO bool = le1(x,y) AND x /= y
    lt2(a,b)  : MACRO bool = le2(a,b) AND a /= b
    min(x,y):T1 = IF le1(x,y) THEN x ELSE y ENDIF
    max(x,y):T1 = IF le1(x,y) THEN x ELSE y ENDIF

    increasing?(f)        : bool = FORALL x,y : le1(x,y) IMPLIES le2(f(x),f(y))
    decreasing?(f)        : bool = FORALL x,y : le1(x,y) IMPLIES le2(f(y),f(x))
    strict_increasing?(f) : bool = FORALL x,y : lt1(x,y) IMPLIES lt2(f(x),f(y))
    strict_decreasing?(f) : bool = FORALL x,y : lt1(x,y) IMPLIES lt2(f(y),f(x))

    constant?(f)          : bool = FORALL x,y : f(x) = f(y)

    monotonic?(f)         : bool = increasing?(f) OR decreasing?(f)
    strict_monotonic?(f)  : bool = strict_increasing?(f) OR strict_decreasing?(f)

    min(f,g):[T1->T2] = LAMBDA x: IF le2(f(x),g(x)) THEN f(x) ELSE g(x) ENDIF
    max(f,g):[T1->T2] = LAMBDA x: IF le2(f(x),g(x)) THEN g(x) ELSE f(x) ENDIF

    

    mid(g,f,h):[T1->T2] = min(max(g,f),h)

    increasing_is_function: JUDGEMENT (increasing?) SUBTYPE_OF [T1->T2]
    decreasing_is_function: JUDGEMENT (decreasing?) SUBTYPE_OF [T1->T2]
    constant_is_function  : JUDGEMENT (constant?)   SUBTYPE_OF [T1->T2]
    monotonic_is_function : JUDGEMENT (monotonic?)  SUBTYPE_OF [T1->T2]

    strict_increasing_is_increasing:
                         JUDGEMENT (strict_increasing?) SUBTYPE_OF (increasing?)
    strict_decreasing_is_decreasing:
                         JUDGEMENT (strict_decreasing?) SUBTYPE_OF (decreasing?)
    strict_monotonic_is_monotonic:
                         JUDGEMENT (strict_monotonic?)  SUBTYPE_OF (monotonic?)

  %  min_preserves_increasing: JUDGEMENT


    END fun_preds_partial

addendum:
  %%% ================ Addendum: generated declarations ================

  % Judgement subtype TCC generated (at line 38, column 33) for  x
      % expected type  (increasing?)
  strict_increasing_is_increasing: OBLIGATION
    FORALL (x: (strict_increasing?)): increasing?(x);

  % Judgement subtype TCC generated (at line 40, column 33) for  x
      % expected type  (decreasing?)
  strict_decreasing_is_decreasing: OBLIGATION
    FORALL (x: (strict_decreasing?)): decreasing?(x);

  % Judgement subtype TCC generated (at line 42, column 33) for  x
      % expected type  (monotonic?)
  strict_monotonic_is_monotonic: OBLIGATION
    FORALL (x: (strict_monotonic?)): monotonic?(x);


body:
  %------------------------------------------------------------------------------
  % Continuous Functions bewteen Scott Topologies
  %
  % All references are to BA Davey and HA Priestly "Introduction to Lattices and
  % Orders", CUP, 1990
  %
  % We give the Domain Theoretical formulation of Continuity
  % (scott_continuous_def) and show that the pointwise order on functions is
  % itself directed complete (pointwise_complete).
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            25/12/07  Initial Version
  %------------------------------------------------------------------------------

  scott_continuity[T1,T2:TYPE, (IMPORTING orders@directed_orders)
                   le1:(directed_complete_partial_order?[T1]),
                   le2:(directed_complete_partial_order?[T2])]: THEORY

  BEGIN

    IMPORTING scott[T1,le1], scott[T2,le2], fun_preds_partial[T1,T2,le1,le2],
              topology@continuity_def[T1,scott_open_sets[T1,le1],
                                      T2,scott_open_sets[T2,le2]],
              topology@continuity[T1,scott_open_sets[T1,le1],
                                  T2,scott_open_sets[T2,le2]]

    D: VAR directed[T1,le1]
    a: VAR T2
    f: VAR [T1->T2]
    g: VAR (increasing?)

  % The following three Lemmata are D&P 3.15 (i)

    lub_set_image:  LEMMA lub_set?(image(g,D))
    directed_image: LEMMA directed?[T2,le2](image(g,D))
    lub_image:      LEMMA le2(lub(image(g,D)),g(lub(D)))

  % The following is D&P 3.15 (ii)

    lub_image_increasing: LEMMA
         (FORALL D: directed?[T2,le2](image(f,D)) AND
                    le2(lub[T2,le2](image(f,D)),f(lub[T1,le1](D))))
         IMPLIES increasing?(f)

    lub_preserving?(f):bool = FORALL D: lub_set?(image(f,D)) IMPLIES 
                                          f(lub(D)) = lub(image(f,D))

    scott_continuous?(f):bool = increasing?(f) AND lub_preserving?(f)

    scott_continuous: TYPE = (scott_continuous?)

    scott_continuous_def: LEMMA continuous?(f) IFF scott_continuous?(f)

    scott_continuous_is_continuous:
                     JUDGEMENT (scott_continuous?) SUBTYPE_OF (continuous?)
    continuous_is_scott_continuous:
                     JUDGEMENT (continuous?)       SUBTYPE_OF (scott_continuous?)
    continuous_is_increasing:
                     JUDGEMENT (continuous?)       SUBTYPE_OF (increasing?)
    continuous_is_lub_preserving:
                     JUDGEMENT (continuous?)       SUBTYPE_OF (lub_preserving?)

    IMPORTING structures@const_fun_def[T1,T2],
              topology@constant_continuity[T1,scott_open_sets[T1,le1],
                                           T2,scott_open_sets[T2,le2]]

    const_scott_continuous: JUDGEMENT const_fun(a) HAS_TYPE scott_continuous

    IMPORTING orders@directed_orders[(scott_continuous?)],
              orders@pointwise_orders[T1,T2]

    pointwise_complete: LEMMA
      directed_complete?[(scott_continuous?)](pointwise(le2))

    scott_continuous_dcpo: LEMMA
      directed_complete_partial_order?[(scott_continuous?)](pointwise(le2))

    IMPORTING scott[(scott_continuous?),(pointwise(le2))]

  END scott_continuity

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 36, column 42) for  image(g, D)
      % expected type  (nonempty?[T2])
  directed_image_TCC1: OBLIGATION
    FORALL (D: directed[T1, le1], g: (increasing?)):
      nonempty?[T2](image[T1, T2](g, D));

  % Subtype TCC generated (at line 37, column 32) for  image(g, D)
      % expected type  SA: (lub_set?)
  lub_image_TCC1: OBLIGATION
    FORALL (D: directed[T1, le1], g: (increasing?)):
      lub_set?[T2, le2](image[T1, T2](g, D));

  % Subtype TCC generated (at line 42, column 36) for  image(f, D)
      % expected type  (nonempty?[T2])
  lub_image_increasing_TCC1: OBLIGATION
    FORALL (f: [T1 -> T2], D): nonempty?[T2](image[T1, T2](f, D));

  % Subtype TCC generated (at line 43, column 34) for  image(f, D)
      % expected type  SA: (lub_set?)
  lub_image_increasing_TCC2: OBLIGATION
    FORALL (f: [T1 -> T2], D):
      directed?[T2, le2](image(f, D)) IMPLIES
       lub_set?[T2, le2](image[T1, T2](f, D));

  % Judgement subtype TCC generated (at line 56, column 29) for  x
      % expected type  (continuous?)
  scott_continuous_is_continuous: OBLIGATION
    FORALL (x: (scott_continuous?)):
      continuous?[T1, scott_open_sets[T1, le1], T2, scott_open_sets[T2, le2]]
          (x);

  % Judgement subtype TCC generated (at line 58, column 29) for  x
      % expected type  (scott_continuous?)
  continuous_is_scott_continuous: OBLIGATION
    FORALL (x: (continuous?)): scott_continuous?(x);

  % Judgement subtype TCC generated (at line 60, column 29) for  x
      % expected type  (increasing?)
  continuous_is_increasing: OBLIGATION
    FORALL (x: (continuous?)): increasing?[T1, T2, le1, le2](x);

  % Judgement subtype TCC generated (at line 62, column 29) for  x
      % expected type  (lub_preserving?)
  continuous_is_lub_preserving: OBLIGATION
    FORALL (x: (continuous?)): lub_preserving?(x);

  % Subtype TCC generated (at line 79, column 39) for
      % (restrict
      %      [[[T1 -> T2], [T1 -> T2]],
      %       [(scott_continuous?), (scott_continuous?)], boolean]
      %      ((pointwise(le2))))
      % expected type  (directed_complete_partial_order?[(scott_continuous?)])
  IMP_scott_TCC1: OBLIGATION
    directed_complete_partial_order?[(scott_continuous?)]
        ((restrict
              [[[T1 -> T2], [T1 -> T2]],
               [(scott_continuous?), (scott_continuous?)], boolean]
              ((pointwise[T1, T2](le2)))));


body:
  %------------------------------------------------------------------------------
  % Definition and properties of Fixpoints
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to BA Davey and HA Priestly "Introduction to Lattices and
  % Orders", CUP, 1990
  %
  % Note carefully:
  %
  % FIX(f)   is the set of all fixpoints of any function.
  % fix(phi) is the least fixpoint of an increasing (ie monotonic) function.
  %
  %   And especially: only when the function (psi) is continuous do we have
  %
  % psi(fix(psi)) = fix(psi)
  %
  %     Version 1.0            25/12/07  Initial Version
  %------------------------------------------------------------------------------

  fixpoints[T:TYPE+, (IMPORTING orders@directed_orders[T])
            <=:(pointed_directed_complete_partial_order?[T])]: THEORY

  BEGIN

    IMPORTING fun_preds_partial[T,T,<=,<=],
              orders@directed_order_props[T,<=]

    n:   VAR nat
    x,y: VAR T
    f,g: VAR [T -> T]
    phi: VAR (increasing?)
    X:   VAR (nonempty?[T])
    D:   VAR directed

    unique_bottom: LEMMA least?(fullset[T],<=)(x) AND
                         least?(fullset[T],<=)(y) IMPLIES x = y

    bottom: (least?(fullset[T],<=))

    bottom_le:  LEMMA bottom <= x
    le_bottom:  LEMMA (x <= bottom) IMPLIES x = bottom
    nonempty_T: LEMMA nonempty?(fullset[T])

    IMPORTING algebra@monoid[[T->T],function_props[T,T,T].o,(LAMBDA x: x)],
              scott[T,<=],
              orders@chain[T,<=],
              fun_preds_partial[nat,T,reals.<=,<=]

    FIX_APPROX(phi):set[T] = image((LAMBDA n: power(phi,n)(bottom)),fullset[nat])
    FIX(f)         :set[T] = {x | f(x) = x}

    lub_add_bottom:       LEMMA lub(D) = lub(add(bottom,D))
    increasing_phi_n:     LEMMA increasing?(power(phi,n))
    increasing_power:     LEMMA increasing?(LAMBDA n: power(phi,n)(bottom))
    fix_approx_nonempty:  LEMMA nonempty?(FIX_APPROX(phi))
    fix_approx_chain:     LEMMA chain?(FIX_APPROX(phi))
    ne_chain_is_directed: LEMMA chain?(X) IMPLIES directed?(<=)(X)
    lub_emptyset:         LEMMA lub(emptyset[T]) = bottom
   
    fix(phi):T = lub(FIX_APPROX(phi))

    member_FIX:           LEMMA member(x,FIX(f)) IMPLIES f(x) = x
    fix_is_least:         LEMMA member(x,FIX(phi)) IMPLIES fix(phi) <= x
    fix_le:               LEMMA fix(phi) <= phi(fix(phi))

    IMPORTING scott_continuity[T,T,<=,<=]

    psi: VAR (continuous?)

    fix_in_FIX:           LEMMA member(fix(psi),FIX(psi))
    nonempty_FIX:         LEMMA nonempty?(FIX(psi))
    fix_prop:             LEMMA psi(fix(psi)) = fix(psi)
    fixpoint_contraction: LEMMA psi(x) <= x => fix(psi) <= x

  END fixpoints

addendum:
  %%% ================ Addendum: generated declarations ================

  % Existence TCC generated (at line 39, column 2) for
      % bottom: (LAMBDA (t: T): least?(t, fullset[T], <=))
  bottom_TCC1: OBLIGATION
    EXISTS (x: (LAMBDA (t: T): least?[T](t, fullset[T], <=))): TRUE;

  % Assuming TCC generated (at line 45, column 12) for
      % algebra@monoid[[T -> T], function_props[T, T, T].o, (LAMBDA x: x)]
      % generated from assumption monoid.fullset_is_monoid
  IMP_monoid_TCC1: OBLIGATION
    monoid?[[T -> T], function_props[T, T, T].o, (LAMBDA x: x)]
        (fullset[[T -> T]]);

  % Subtype TCC generated (at line 53, column 43) for  add(bottom, D)
      % expected type  SA: (lub_set?)
  lub_add_bottom_TCC1: OBLIGATION
    FORALL (D: directed[T, <=]): lub_set?[T, <=](add[T](bottom, D));

  % Subtype TCC generated (at line 59, column 34) for  emptyset[T]
      % expected type  SA: (lub_set?)
  lub_emptyset_TCC1: OBLIGATION lub_set?[T, <=](emptyset[T]);

  % Subtype TCC generated (at line 61, column 19) for  FIX_APPROX(phi)
      % expected type  SA: (lub_set?)
  fix_TCC1: OBLIGATION
    FORALL (phi: (increasing?[T, T, <=, <=])):
      lub_set?[T, <=](FIX_APPROX(phi));


body:
  %------------------------------------------------------------------------------
  % Admissible Predicates
  %
  %     Author: David Lester, Manchester University, NIA, Universite Perpignan
  %
  % If a predicate is "admissible" then we have an induction principle for
  % fixpoints (fixpoint_induction).
  %
  %     Version 1.0            1/11/06  Initial Version
  %------------------------------------------------------------------------------

  admissible[T:TYPE+, (IMPORTING orders@directed_orders[T])
            <=:(pointed_directed_complete_partial_order?[T])]: THEORY

  BEGIN

    IMPORTING fixpoints[T,<=]

    x:   VAR T
    D:   VAR set[T]
    q:   VAR pred[T]
    phi: VAR (increasing?[T,T,<=,<=])

  % An admissible predicate is a lub-preserving function between T and the
  % special two-point pointed DCPO: TRUE < FALSE, that is also TRUE for bottom.

    IMPORTING scott[bool,when], scott_continuity[T,bool,<=,when]

    admissible_pred?(p:pred[T]):bool
     = FORALL D: empty?(D) OR directed?(D) => (FORALL (x:(D)): p(x)) => p(lub(D))

    admissible_pred: TYPE+ = (admissible_pred?) CONTAINING (LAMBDA x: TRUE)

    p: VAR admissible_pred

    fixpoint_induction: LEMMA (FORALL x: p(x) => p(phi(x))) => p(fix(phi))

  END admissible

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 27, column 23) for  WHEN
      % expected type  (directed_complete_partial_order?[boolean])
  IMP_scott_TCC1: OBLIGATION directed_complete_partial_order?[boolean](WHEN);

  % Subtype TCC generated (at line 30, column 38) for  D
      % expected type  (nonempty?[T])
  admissible_pred?_TCC1: OBLIGATION
    FORALL (D): NOT empty?(D) IMPLIES nonempty?[T](D);

  % Subtype TCC generated (at line 30, column 76) for  D
      % expected type  SA: (lub_set?)
  admissible_pred?_TCC2: OBLIGATION
    FORALL (p: pred[T], D):
      (FORALL (x: (D)): p(x)) AND (empty?(D) OR directed?(D)) IMPLIES
       lub_set?[T, <=](D);

  % Subtype TCC generated (at line 32, column 58) for  (LAMBDA x: TRUE)
      % expected type  admissible_pred
  admissible_pred_TCC1: OBLIGATION admissible_pred?((LAMBDA x: TRUE));


body:
  %------------------------------------------------------------------------------
  % Dual Fixpoint Induction
  %
  % All references are to BA Davey and HA Priestly "Introduction to Lattices and
  % Orders", CUP, 1990
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            25/12/07  Initial Version
  %------------------------------------------------------------------------------

  dual_fixpoints[T1,T2:TYPE+, (IMPORTING orders@directed_orders)
                 le1:(pointed_directed_complete_partial_order?[T1]),
                 le2:(pointed_directed_complete_partial_order?[T2])]: THEORY

  BEGIN

    IMPORTING orders@product_orders[T1,T2],
              fixpoints[T1,le1],
              fixpoints[T2,le2],
              fixpoints[[T1,T2],(le1*le2)],
              admissible[[T1,T2],(le1*le2)]

    x: VAR T1
    y: VAR T2
    phi: VAR (increasing?[T1,T1,le1,le1])
    psi: VAR (increasing?[T2,T2,le2,le2])
    D:   VAR directed[[T1,T2],(le1*le2)]

    IMPORTING scott_continuity[[T1,T2],bool,(le1*le2),when]

    p: VAR admissible_pred[[T1,T2],(le1*le2)]

    dual_fixpoint_induction: LEMMA 
      (FORALL x,y: p(x,y) IMPLIES p(phi(x),psi(y))) IMPLIES p(fix(phi),fix(psi))

  END dual_fixpoints

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 30, column 52) for  WHEN
      % expected type  (directed_complete_partial_order?[boolean])
  IMP_scott_continuity_TCC1: OBLIGATION
    directed_complete_partial_order?[boolean](WHEN);


body:
  %------------------------------------------------------------------------------
  % Composition is Continuous
  %
  % All references are to BA Davey and HA Priestly "Introduction to Lattices and
  % Orders", CUP, 1990
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            25/12/07  Initial Version
  %------------------------------------------------------------------------------
  scott_composition_continuity[T1,T2,T3:TYPE, (IMPORTING orders@directed_orders)
                              le1:(directed_complete_partial_order?[T1]),
                              le2:(directed_complete_partial_order?[T2]),
                              le3:(directed_complete_partial_order?[T3])]: THEORY

  BEGIN

    IMPORTING scott_continuity[T1,T2,le1,le2],
              scott_continuity[T2,T3,le2,le3],
              scott_continuity[T1,T3,le1,le3],
              topology@composition_continuity[T1,scott_open_sets[T1,le1],
                                              T2,scott_open_sets[T2,le2],
                                              T3,scott_open_sets[T3,le3]]

    f: VAR scott_continuous[T2,T3,le2,le3]
    g: VAR scott_continuous[T1,T2,le1,le2]

    composition_scott_continuous: JUDGEMENT
      o(f:(scott_continuous?[T2,T3,le2,le3]),
        g:(scott_continuous?[T1,T2,le1,le2]))
                                       HAS_TYPE scott_continuous[T1,T3,le1,le3]

  END scott_composition_continuity


body:
  %------------------------------------------------------------------------------
  % Identity Function is Continuous
  %
  % All references are to BA Davey and HA Priestly "Introduction to Lattices and
  % Orders", CUP, 1990
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            25/12/07  Initial Version
  %------------------------------------------------------------------------------

  scott_identity_continuity[T:TYPE,(IMPORTING orders@directed_orders[T])
                            le:(directed_complete_partial_order?)]: THEORY

  BEGIN

    IMPORTING scott_continuity[T,T,le,le],
              topology@identity_continuity[T,scott_open_sets[T,le]]

    id_scott_continuous: JUDGEMENT I[T] HAS_TYPE scott_continuous

  END scott_identity_continuity


body:
  %------------------------------------------------------------------------------
  % Properties of Continuous Functions between Scott Topologies
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to BA Davey and HA Priestly "Introduction to Lattices and
  % Orders", CUP, 1990
  %
  % Extensions to orders@pointwise_orders.
  % Note that pointwise ordering only preserves directed completeness for
  % continuous functions.
  %
  %     Version 1.0            25/12/07  Initial Version
  %------------------------------------------------------------------------------

  pointwise_orders_aux[T1,T2:TYPE]: THEORY

  BEGIN

    IMPORTING orders@pointwise_orders[T1,T2],
              orders@directed_orders,
              scott_continuity

    d1: VAR (directed_complete_partial_order?[T1])
    d2: VAR (directed_complete_partial_order?[T2])
    p1: VAR (pointed_directed_complete_partial_order?[T1])
    p2: VAR (pointed_directed_complete_partial_order?[T2])

    continuous_pointwise(d1,d2)(f,g:scott_continuous[T1,T2,(d1),(d2)]):bool
      = pointwise(d2)(f,g)

    continuous_pointwise_preserves_directed_complete_partial_order: JUDGEMENT
      continuous_pointwise(d1,d2) HAS_TYPE
        (directed_complete_partial_order?[(scott_continuous?[T1,T2,(d1),(d2)])])

    continuous_pointwise_preserves_pointed_directed_complete_partial_order:
      JUDGEMENT
       continuous_pointwise(p1,p2) HAS_TYPE
        (pointed_directed_complete_partial_order?
            [(scott_continuous?[T1,T2,(p1),(p2)])])

  END pointwise_orders_aux

addendum:
  %%% ================ Addendum: generated declarations ================

  % Judgement subtype TCC generated (at line 33, column 4) for
      % continuous_pointwise(d1, d2)
      % expected type  (directed_complete_partial_order?
                     %      [(scott_continuous?[T1, T2, (d1), (d2)])])
  continuous_pointwise_preserves_directed_complete_partial_order: OBLIGATION
    FORALL (d1, d2):
      directed_complete_partial_order?
          [(scott_continuous?[T1, T2, (d1), (d2)])]
          (continuous_pointwise(d1, d2));

  % Judgement subtype TCC generated (at line 38, column 5) for
      % continuous_pointwise(p1, p2)
      % expected type  (pointed_directed_complete_partial_order?
                     %      [(scott_continuous?[T1, T2, (p1), (p2)])])
  continuous_pointwise_preserves_pointed_directed_complete_partial_order: OBLIGATION
    FORALL (p1, p2):
      pointed_directed_complete_partial_order?
          [(scott_continuous?[T1, T2, (p1), (p2)])]
          (continuous_pointwise(p1, p2));


body:
  %------------------------------------------------------------------------------
  % Extras for PartialFunctionDefinitions
  %
  %       Author: David Lester <dlester@cs.man.ac.uk> Manchester University
  %
  %       Version 1.0          03/30/06
  %------------------------------------------------------------------------------

  partial_function_props[X,Y:TYPE]: THEORY

  BEGIN

    IMPORTING PartialFunctionDefinitions[X,Y],
              orders@lift_props[Y]

    f,f1,f2: VAR LiftPartialFunction

    dom(f):  set[X] = dom(LPartFun_to_SPartFun(f))
    range(f):set[Y] = image(fun(LPartFun_to_SPartFun(f)),
                            dom(LPartFun_to_SPartFun(f)))
    graph(f):set[[X,Y]] = graph(fun(LPartFun_to_SPartFun(f)))

    x:       VAR X
    y,y1,y2: VAR Y
    Z:       VAR set[Y]
    z:       VAR lift[Y]
    h:       VAR [X->Y]

    member_dom:   LEMMA dom(f)(x) IFF f(x) /= bottom
    member_graph: LEMMA (EXISTS y: graph(f)(x,y)) IFF f(x) /= bottom
    graph_eq:     LEMMA graph(f1) = graph(f2) IFF f1 = f2

    graph?(G:set[[X,Y]]):bool
      = FORALL x,y1,y2: G(x,y1) AND G(x,y2) IMPLIES y1 = y2

    g: VAR (graph?)

    from_graph(g):LiftPartialFunction
     = LAMBDA x: LET Z = {y | g(x,y)} IN 
                 IF nonempty?(Z) THEN up(choose(Z)) ELSE bottom ENDIF

    graph_is_graph?:  LEMMA graph?(graph(f))
    graph_from_graph: LEMMA graph(from_graph(g)) = g
    from_graph_graph: LEMMA from_graph(graph(f)) = f

    lifted(h):LiftPartialFunction = LAMBDA x: up(h(x))

  END partial_function_props

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 44, column 37) for  graph(f)
      % expected type  (graph?)
  from_graph_graph_TCC1: OBLIGATION
    FORALL (f: LiftPartialFunction[X, Y]): graph?(graph(f));


body:
  top: THEORY
  %----------------------------------------------------------------------------
  %
  % Infinite Series
  %
  % Author: Ricky W. Butler        11/01/00
  %         David Lester           12/01/03   (generalizations)
  %         (Manchester University)
  % 
  % CHANGES:
  %
  %     Version 1.0          -- 11/01/00
  %     Version 1.1 (Lester) -- updated  nth_derivatives and taylors theories
  %     Version 1.2          -- 7/8/04   proved axioms, major upgrade
  %                                      new theory: taylor_series
  %     Version 1.3          -- 1/5/05   update to analysis name changes%
  %     Version 1.4          -- 3/22/06  simplified powerseq definition and
  %                                      moved nth_derivatives and taylors
  %                                      to analysis library
  %     Version 1.5          -- 12/14/07 added series_lems, absconv theories
  %     Version 1.6          -- 9/15/09  series_aux
  %----------------------------------------------------------------------------
  BEGIN

     IMPORTING series,               % definition + properies of infinite series
               series_lems,          % New basic theorems
               series_aux,           % more theorems from David Lester
               absconv_series,       % Absolute convergence
               power_series,         % definition + properies of power series
               trig_fun,             % definition of trigonometric functions
               trig_props,           % basic trig identities
               taylor_series,        % expansion into Taylor's series
               power_series_deriv,   % derivative of a power series 
               power_series_integ    % integral of a power series 

  END top


body:
  series: THEORY
  %------------------------------------------------------------------------------
  % The series theory introduces and defines properties of the (infinite) series 
  % function that sums a sequence up to n:
  %
  %                               n
  %                             ----
  %  series(a) =   (LAMBDA n:   \     a(j) )
  %                             /
  %                              ----
  %                             j = 0
  %
  %
  %                                 n
  %                               ----
  %  series(a,m) =  (LAMBDA n:    \     a(j) )
  %                               /
  %                               ----
  %                               j = m
  %
  %  The theory develops convergence properties of the series as n --> infinity
  %
  %      convergent?(series(a)) IMPLIES convergence(a,0)
  %     
  %      comparison test
  %   
  %      convergence(series(geometric(x)), 1 / (1 - x))
  %   
  %      ratio test
  %
  % Developed  by Ricky W. Butler      NASA Langley Research Center
  % 
  %      Version 1.0    last modified 10/02/00
  %   
  %------------------------------------------------------------------------------
  BEGIN
   
  %   analysis: LIBRARY "../analysis"
  %   reals: LIBRARY "../reals"

     IMPORTING analysis@convergence_ops,
               reals@sigma_nat 
  %             prelude_aux_series


     i: VAR int
     n,m,N,k: VAR nat
     pn: VAR posnat
     x,l1,l2,c: VAR real

     a,b,s: VAR sequence[real]

     series(a): sequence[real] =  (LAMBDA (n: nat): sigma(0, n, a))

     series(a,m): sequence[real] =  (LAMBDA (n: nat): sigma(m, n, a))

  %   Convergent_Series: TYPE = {s: sequence[real] | convergent?(series(s))}

     conv_series?(a): bool = convergent?(series(a))

     inf_sum(cs: (conv_series?)): real = limit(series(cs))

     conv_series?(a,m): bool = convergent?(series(a,m))

     inf_sum(m: nat, a: {s | conv_series?(s,m)}): real = limit(series(a,m))

     abs(a): sequence[real] = (LAMBDA (n: nat): abs(a(n)))


     series_diff  : LEMMA series(a) - series(b) = series(a-b)

     series_sum   : LEMMA series(a) + series(b) = series(a+b)

     series_m_diff: LEMMA series(a,m) - series(b,m) = series(a-b,m)

     series_m_sum : LEMMA series(a,m) + series(b,m) = series(a+b,m)
     
     series_m_scal: LEMMA  c*series(a,m) = series(c*a,m)

     series_m_eq  : LEMMA (FORALL k: k >= m IMPLIES a(k) = b(k))
                                  IMPLIES series(a,m)  = series(b,m) 

     series_scal  : LEMMA c*series(a) =  series(LAMBDA n: c*a(n))



  % -------------------- convergence properties of series -------------------

     conv_series_terms_to_0: THEOREM convergent?(series(a)) IMPLIES
                                    convergence(a,0)

     series_limit_0    : COROLLARY convergent?(series(a)) IMPLIES
                                    limit(a) = 0



     convergent_abs    : THEOREM convergent?(series(abs(a)))
                                IMPLIES convergent?(series(a))


     partial_sums      :    THEOREM convergent?(series(a)) IFF
                               (FORALL (epsilon: posreal): 
                                   (EXISTS (N: posint):
                                      (FORALL n,m: (n > m AND m >= N) IMPLIES
                                          abs(sigma(m+1,n,a)) < epsilon)))

     zero_series_conv  : LEMMA convergent?(series(LAMBDA n: 0))

     zero_series_limit : LEMMA limit(series(LAMBDA n: 0)) = 0


  %  --------- only behavior at end matters, so shifting changes nothing --------

     tail_series_conv  : LEMMA convergent?(series(a)) 
                                   IMPLIES convergent?(series((LAMBDA n: a(n+N))))

     tail_series_conv2 : LEMMA convergent?(series((LAMBDA n: a(n+N)))) IMPLIES
                                    convergent?(series(a)) 
     
     conv_series_shift : LEMMA convergent?(series(a)) 
                                   IFF convergent?(series((LAMBDA n: a(n+N))))


     tail_conv         : LEMMA convergent?(series(a)) AND
                                 (EXISTS (N: nat): (FORALL (n: nat): 
                                            n >= N IMPLIES a(n) = b(n)))
                                                  IMPLIES convergent?(series(b))

     end_series_conv   : THEOREM convergent?(series(a)) IFF convergent?(series(a,m)) 
                                  
     scal_series_conv   : LEMMA convergent?(series(a))
                                  IMPLIES convergent?(c*series(a))

     cnz: VAR nzreal
     conv_series_scal  : LEMMA convergent?(cnz*series(a))  IFF convergent?(series(a)) 

     limit_series_shift: LEMMA convergent?(series(a)) IMPLIES
                        limit(series(a)) = sigma(0,pn-1,a)  
                                  + limit(series(LAMBDA n: a(n+pn)))

     limit_pos         : LEMMA (FORALL n: a(n) > 0) AND convergent?(a)
                                     IMPLIES limit(a) >= 0
                            
     series_first : LEMMA convergent?(series(a)) IMPLIES
                            limit(series(a)) = a(0) + limit(series(a,1)) 

     inf_sum_scal: LEMMA convergent?(series(a, k)) IMPLIES  
                               c*inf_sum(k,a) = inf_sum(k,c*a) 


  % -------------------- comparison test --------------------

     comparison_test   : THEOREM convergent?(series(b)) AND
                                   (FORALL n: abs(a(n)) <= b(n))
                                         IMPLIES convergent?(series(a))


     comparison_test_gen: THEOREM convergent?(series(b)) AND
                            (EXISTS (N: nat): (FORALL (n: nat):
                                n >= N IMPLIES abs(a(n)) <= b(n)))
                           IMPLIES convergent?(series(a))


     inf_sum_eq: LEMMA (FORALL k: k >= m IMPLIES a(k) = b(k)) AND
                       conv_series?(a,m) AND conv_series?(b,m) IMPLIES
                             inf_sum(m,a) = inf_sum(m,b) 


     inf_sum_le: LEMMA (FORALL (n: upfrom(m)): abs(a(n)) <= b(n)) AND
                       convergent?(series(b,m))
                           IMPLIES inf_sum(m,a) <= inf_sum(m,b)


     inf_sum_le_abs: LEMMA (FORALL (n: upfrom(m)): abs(a(n)) <= b(n)) AND
                       convergent?(series(b,m))
                           IMPLIES abs(inf_sum(m,a)) <= inf_sum(m,b)

     inf_sum_triangle: LEMMA convergent?(series(abs(a))) IMPLIES
                               abs(inf_sum(m, a)) <= inf_sum(m, abs(a))


  %  -------------------- series sum -------------------------

     series_sum_conv   : LEMMA convergent?(series(a)) AND convergent?(series(b))
                                 IMPLIES convergent?(series(a+b))


     series_sum_convergence: LEMMA convergence(series(a), l1) AND
                                   convergence(series(b), l2)
                       IMPLIES convergence(series(a + b), l1+l2)

     inf_sum_of_sum: LEMMA convergent?(series(a)) AND convergent?(series(b))
                 IMPLIES inf_sum(a+b) = inf_sum(a) + inf_sum(b)


  % ----------- geometric series ----------------------------

     abs_x_to_n_conv   : LEMMA abs(x) < 1 IMPLIES
                                   convergent?((LAMBDA (n: nat): abs(x)^n))   

     cnv_seq_abs_x_to_n  : LEMMA abs(x) < 1 IMPLIES
                                   limit(LAMBDA (n: nat): abs(x)^n) = 0  

     x_to_n_conv       : LEMMA abs(x) < 1 IMPLIES
                                   convergent?((LAMBDA (n: nat): x^n))   

     convergence_x_to_n: LEMMA abs(x) < 1 IMPLIES
                                   convergence((LAMBDA (n: nat): c*x^n), 0)   

     geometric(x): sequence[real] = (LAMBDA n: x^n)

     sigma_geometric_aux   : LEMMA 
                           (1-x)* sigma(0, n, geometric(x)) = (1 - x^(n+1))

     sigma_geometric   : LEMMA x /= 1 IMPLIES
                            sigma(0, n, geometric(x)) = (1 - x^(n+1))/(1 - x)

     geometric_series  : LEMMA abs(x) < 1 IMPLIES
                            convergence(series(geometric(x)), 1 / (1 - x))

     geometric_conv    : COROLLARY abs(x) < 1 IMPLIES
                                      convergent?(series(geometric(x)))


     const_geometric_series: LEMMA abs(x) < 1 IMPLIES
                                 convergence(series(c*geometric(x)), c / (1 - x))

     geometric_sum     : LEMMA abs(x) < 1 IMPLIES
                                 inf_sum(geometric(x)) = 1/(1-x)

  % -------------------- ratio test --------------------

     rho: VAR posreal

     scaf_abs: LEMMA (FORALL (n: nat):  abs(a(n+1)) <= rho* abs(a(n)))
                         IMPLIES abs(a(n)) <= abs(a(0))*rho^n

     ratio_test: THEOREM (FORALL n: a(n) /= 0) AND
                            (EXISTS (rho: posreal): rho < 1 AND
                              (FORALL (n: nat): abs(a(n+1)/a(n)) <= rho))
                          IMPLIES convergent?(series(a))

     ratio_test_gen: THEOREM (FORALL n: a(n) /= 0) AND
                            (EXISTS (rho: posreal): rho < 1 AND
                              (EXISTS (N: nat): (FORALL (n: nat):
                             n >= N IMPLIES  abs(a(n+1)/a(n)) <= rho)))
                            IMPLIES convergent?(series(a))


     ratio_test_gt_N: THEOREM (EXISTS (N: nat): (EXISTS (rho: posreal): 
                                  rho < 1 AND
                                (FORALL (n: nat): n >= N IMPLIES a(n) /= 0 
                                          AND abs(a(n+1)/a(n)) <= rho)))
                            IMPLIES convergent?(series(a))


     ratio_test_lim: THEOREM (FORALL n: a(n) /= 0) AND
                             convergent?(LAMBDA n: abs(a(n+1)/a(n))) AND
                             limit(LAMBDA n: abs(a(n+1)/a(n))) < 1
                                IMPLIES convergent?(series(a))


  END series

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 53, column 59) for  n
      % expected type  T_high[nat]
  series_TCC1: OBLIGATION
    FORALL (n: nat): n >= 0 OR (EXISTS (j: nat): n <= j);

  % Subtype TCC generated (at line 61, column 45) for  series(cs)
      % expected type  (convergent?)
  inf_sum_TCC1: OBLIGATION
    FORALL (cs: (conv_series?)): convergent?(series(cs));

  % Subtype TCC generated (at line 65, column 61) for  series(a, m)
      % expected type  (convergent?)
  inf_sum_TCC2: OBLIGATION
    FORALL (m: nat, a: {s | conv_series?(s, m)}): convergent?(series(a, m));

  % Subtype TCC generated (at line 93, column 40) for  a
      % expected type  (convergent?)
  series_limit_0_TCC1: OBLIGATION
    FORALL (a: sequence[real]): convergent?(series(a)) IMPLIES convergent?(a);

  % Subtype TCC generated (at line 109, column 35) for  series(LAMBDA n: 0)
      % expected type  (convergent?)
  zero_series_limit_TCC1: OBLIGATION convergent?(series(LAMBDA n: 0));

  % Subtype TCC generated (at line 138, column 49) for  pn - 1
      % expected type  T_high[nat]
  limit_series_shift_TCC1: OBLIGATION
    FORALL (a: sequence[real], pn: posnat):
      convergent?(series(a)) IMPLIES
       pn - 1 >= 0 OR (EXISTS (j: nat): pn - 1 <= j);

  % Subtype TCC generated (at line 139, column 40) for
      % series(LAMBDA n: a(n + pn))
      % expected type  (convergent?)
  limit_series_shift_TCC2: OBLIGATION
    FORALL (a: sequence[real], pn: posnat):
      convergent?(series(a)) IMPLIES convergent?(series(LAMBDA n: a(n + pn)));

  % Subtype TCC generated (at line 145, column 58) for  series(a, 1)
      % expected type  (convergent?)
  series_first_TCC1: OBLIGATION
    FORALL (a: sequence[real]):
      convergent?(series(a)) IMPLIES convergent?(series(a, 1));

  % Subtype TCC generated (at line 148, column 41) for  a
      % expected type  {s | conv_series?(s, k)}
  inf_sum_scal_TCC1: OBLIGATION
    FORALL (a: sequence[real], k: nat):
      convergent?(series(a, k)) IMPLIES conv_series?(a, k);

  % Subtype TCC generated (at line 148, column 56) for  c * a
      % expected type  {s | conv_series?(s, k)}
  inf_sum_scal_TCC2: OBLIGATION
    FORALL (a: sequence[real], c: real, k: nat):
      convergent?(series(a, k)) IMPLIES conv_series?(*[nat](c, a), k);

  % Subtype TCC generated (at line 171, column 43) for  a
      % expected type  {s | conv_series?(s, m)}
  inf_sum_le_TCC1: OBLIGATION
    FORALL (a, b: sequence[real], m: nat):
      (convergent?(series(b, m)) AND
        (FORALL (n: upfrom(m)): abs(a(n)) <= b(n)))
       IMPLIES conv_series?(a, m);

  % Subtype TCC generated (at line 171, column 59) for  b
      % expected type  {s | conv_series?(s, m)}
  inf_sum_le_TCC2: OBLIGATION
    FORALL (a, b: sequence[real], m: nat):
      (convergent?(series(b, m)) AND
        (FORALL (n: upfrom(m)): abs(a(n)) <= b(n)))
       IMPLIES conv_series?(b, m);

  % Subtype TCC generated (at line 179, column 44) for  a
      % expected type  {s | conv_series?(s, m)}
  inf_sum_triangle_TCC1: OBLIGATION
    FORALL (a: sequence[real], m: nat):
      convergent?(series(abs(a))) IMPLIES conv_series?(a, m);

  % Subtype TCC generated (at line 179, column 62) for  abs(a)
      % expected type  {s | conv_series?(s, m)}
  inf_sum_triangle_TCC2: OBLIGATION
    FORALL (a: sequence[real], m: nat):
      convergent?(series(abs(a))) IMPLIES conv_series?(abs(a), m);

  % Subtype TCC generated (at line 193, column 31) for  a + b
      % expected type  (conv_series?)
  inf_sum_of_sum_TCC1: OBLIGATION
    FORALL (a, b: sequence[real]):
      convergent?(series(b)) AND convergent?(series(a)) IMPLIES
       conv_series?((+[nat])(a, b));

  % Subtype TCC generated (at line 193, column 46) for  a
      % expected type  (conv_series?)
  inf_sum_of_sum_TCC2: OBLIGATION
    FORALL (a, b: sequence[real]):
      convergent?(series(b)) AND convergent?(series(a)) IMPLIES
       conv_series?(a);

  % Subtype TCC generated (at line 193, column 59) for  b
      % expected type  (conv_series?)
  inf_sum_of_sum_TCC3: OBLIGATION
    FORALL (a, b: sequence[real]):
      convergent?(series(b)) AND convergent?(series(a)) IMPLIES
       conv_series?(b);

  % Subtype TCC generated (at line 199, column 70) for  n
      % expected type  {i: int | abs(x) /= 0 OR i >= 0}
  abs_x_to_n_conv_TCC1: OBLIGATION
    FORALL (x: real):
      abs(x) < 1 IMPLIES (FORALL (n: nat): abs(x) /= 0 OR n >= 0);

  % Subtype TCC generated (at line 202, column 39) for
      % LAMBDA (n: nat): abs(x) ^ n
      % expected type  (convergent?)
  cnv_seq_abs_x_to_n_TCC1: OBLIGATION
    FORALL (x: real):
      abs(x) < 1 IMPLIES convergent?(LAMBDA (n: nat): abs(x) ^ n);

  % Subtype TCC generated (at line 205, column 65) for  n
      % expected type  {i: int | x /= 0 OR i >= 0}
  x_to_n_conv_TCC1: OBLIGATION
    FORALL (x: real): abs(x) < 1 IMPLIES (FORALL (n: nat): x /= 0 OR n >= 0);

  % Subtype TCC generated (at line 210, column 47) for  n
      % expected type  {i: int | x /= 0 OR i >= 0}
  geometric_TCC1: OBLIGATION FORALL (x: real, n): x /= 0 OR n >= 0;

  % Subtype TCC generated (at line 213, column 68) for  (n + 1)
      % expected type  {i: int | x /= 0 OR i >= 0}
  sigma_geometric_aux_TCC1: OBLIGATION
    FORALL (n: nat, x: real): x /= 0 OR (n + 1) >= 0;

  % Subtype TCC generated (at line 216, column 69) for  (1 - x)
      % expected type  nznum
  sigma_geometric_TCC1: OBLIGATION
    FORALL (x: real): x /= 1 IMPLIES (1 - x) /= 0;

  % Subtype TCC generated (at line 219, column 65) for  (1 - x)
      % expected type  nznum
  geometric_series_TCC1: OBLIGATION
    FORALL (x: real): abs(x) < 1 IMPLIES (1 - x) /= 0;

  % Subtype TCC generated (at line 229, column 39) for  geometric(x)
      % expected type  (conv_series?)
  geometric_sum_TCC1: OBLIGATION
    FORALL (x: real): abs(x) < 1 IMPLIES conv_series?(geometric(x));

  % Subtype TCC generated (at line 236, column 58) for  n
      % expected type  {i: int | rho /= 0 OR i >= 0}
  scaf_abs_TCC1: OBLIGATION
    FORALL (a: sequence[real], n1: nat, rho: posreal):
      (FORALL (n: nat): abs(a(n + 1)) <= rho * abs(a(n))) IMPLIES
       rho /= 0 OR n1 >= 0;

  % Subtype TCC generated (at line 240, column 57) for  a(n)
      % expected type  nznum
  ratio_test_TCC1: OBLIGATION
    FORALL (a: sequence[real]):
      (FORALL n: a(n) /= 0) IMPLIES
       (FORALL (rho: posreal):
          rho < 1 IMPLIES (FORALL (n1: nat): a(n1) /= 0));

  % Subtype TCC generated (at line 258, column 60) for  a(n)
      % expected type  nznum
  ratio_test_lim_TCC1: OBLIGATION
    FORALL (a: sequence[real]):
      (FORALL n: a(n) /= 0) IMPLIES (FORALL (n1): a(n1) /= 0);


body:
  power_series: THEORY
  %----------------------------------------------------------------------------
  %
  % Definition of power series:
  %
  %  		            n
  %		          ----
  %  powerseries(a)(x) =    \     a(k)*x^k
  %		          /
  %		          ----
  %		          k = 0
  %
  %  		            n
  %		          ----
  %  powerseries(a,m)(x) =  \     a(k)*x^k
  %		          /
  %		          ----
  %		          k = m
  %
  %
  % Author: Ricky W. Butler        10/2/00
  %
  % NOTES:
  %  * powerseq is defined using IF-THEN-ELSE to avoid 0^0
  %
  %----------------------------------------------------------------------------
  BEGIN
     
  %   reals: LIBRARY "../reals"

     IMPORTING series, ints@factorial, reals@exponent_props

     x,r,y: VAR real
     c,px: VAR posreal
     x1,z: VAR nonzero_real
     n,m: VAR nat
     a: VAR sequence[real]
     S: VAR set[real]
     pn: VAR posnat

  %   powerseq(a,x): sequence[real] = (LAMBDA (k: nat): a(k)*x^k)
  %   rule out 0^0

     hat_02n: LEMMA 0^pn = 0


     AUTO_REWRITE+ expt_x0         % LEMMA x^0 = 1
     AUTO_REWRITE+ expt_x1         % LEMMA x^1 = x
     AUTO_REWRITE+ expt_1i         % LEMMA 1^i = 1
     AUTO_REWRITE+ hat_02n         % LEMMA 0^pn = 0

     powerseq(a,x): sequence[real] = (LAMBDA (k: nat): a(k)*x^k)


     powerseries(a)(x): sequence[real] = series(powerseq(a,x))

     powerseries(a,m)(x): sequence[real] = series(powerseq(a,x),m)

     absolutely_convergent_series?(a): boolean = convergent?(series(abs(a)))

     divergent_series?(a): boolean = NOT convergent?(series(a))


     powerseries_bounded: LEMMA convergent?(powerseries(a)(x)) IMPLIES
                                  bounded?(powerseq(a, x))
                                  



  %  *** if convergent at one point x1, then abs convergent within (-x1,x1) ***
                                  
     powerseries_conv_point: THEOREM convergent?(powerseries(a)(x1)) AND
                                   abs(x) < abs(x1)
                                      IMPLIES 
                            absolutely_convergent_series?(powerseq(a,x))

     powerseries_conv: COROLLARY convergent?(powerseries(a)(x)) AND
                                   abs(y) < abs(x)
                                      IMPLIES 
                                 convergent?(powerseries(a)(y))


     powerseries_diverg: COROLLARY divergent_series?(powerseq(a,x1)) AND
                                   abs(x) > abs(x1)
                                      IMPLIES 
                            divergent_series?(powerseq(a,x))


     series_convergent_within(a,c): bool =
         (FORALL x: abs(x) < c IMPLIES convergent?(series(powerseq(a,x))))

     series_divergent_outside(a,c): bool =
         (FORALL x:  abs(x) > c IMPLIES divergent_series?(powerseq(a,x)))

     series_convergent_only_at_0(a): bool = 
         convergent?(series(powerseq(a,0))) AND
         (FORALL x:  x /= 0 IMPLIES divergent_series?(powerseq(a,x)))
   
  %  ------ behavior of series at x = c or x = -c is not predictable ------


     zero_powerseries_conv: LEMMA convergent?(powerseries(a)(0))

     powerseries_three_cases: THEOREM
             (FORALL (x: real): convergent?(powerseries(a)(x))) OR
             (series_convergent_only_at_0(a)) OR
             (EXISTS (r: posreal): series_convergent_within(a,r) AND
                                   series_divergent_outside(a,r))

     interval(c): set[real] = {x: real | -c < x AND x < c}

     powerseries_conv_abs_intv: LEMMA 
           (FORALL (x: (interval(c))): convergent?(series(powerseq(a,x)))) 
      IMPLIES (FORALL (x: (interval(c))): convergent?(series(abs(powerseq(a,x)))))


  %  ----- old form retained to preserve old proofs -----

     apowerseq(a,x): sequence[real] = (LAMBDA (k: nat): IF k = 0 THEN a(0)
                                                        ELSE a(k)*x^k
                                                        ENDIF)

     apow_rew: LEMMA powerseq(a,x) = apowerseq(a,x)

  %  to fix old proofs replace (expand "powerseq")
  %                    with    (rewrite "apow_rew") (expand "apowerseq")


  END power_series

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 52, column 60) for  k
      % expected type  {i: int | x /= 0 OR i >= 0}
  powerseq_TCC1: OBLIGATION FORALL (x: real, k: nat): x /= 0 OR k >= 0;


body:
  power_series_conv[T: TYPE from real]: THEORY
  %----------------------------------------------------------------------------
  %
  % Infinite sum of power series:
  %  		                 n
  %		               ----
  %   inf_sum(a)(x) =  limit     \     a(k)*x^k
  %		     n -> inf  /
  %		               ----
  %		               k = 0
  %
  % The theory parameter T is the domain of convergence  of the power series.  
  % In theory power_series this is shown to be either be all of the reals or 
  % the interval {x| -R < x < R} where R is the radius of convergence
  %
  % Author: Ricky W. Butler        10/2/00
  %
  %
  %----------------------------------------------------------------------------
  BEGIN
     
     ASSUMING
       x: VAR T

       IMPORTING power_series, analysis@deriv_domain_def

       not_one_element  : ASSUMPTION not_one_element?[T]

       deriv_domain     : ASSUMPTION deriv_domain?[T]

       open            : ASSUMPTION 
           FORALL (x : T) : EXISTS (delta : posreal): FORALL (y: real):
                              abs(x-y) < delta IMPLIES T_pred(y) 


     ENDASSUMING

     n,m,N: VAR nat
     a: VAR sequence[real]

     AUTO_REWRITE- abs_0
     AUTO_REWRITE- abs_nat


  %  ----- convergent over whole domain -----

     conv_powerseries?(a): bool = (FORALL  x: convergent?(powerseries(a)(x)))

     Inf_sum(a: (conv_powerseries?))(x): real = limit(powerseries(a)(x))

     conv_powerseries?(a,m): bool = (FORALL x: convergent?(powerseries(a,m)(x)))

     Inf_sum(m: nat, a: {a | conv_powerseries?(a,m)})(x): real = 
                               limit(powerseries(a,m)(x))

     end_powerseries_conv   : THEOREM conv_powerseries?(a) IFF
                                          conv_powerseries?(a,m) 

  %   t1: LEMMA   


     Inf_inf: LEMMA conv_powerseries?(a) IMPLIES
                       Inf_sum(a) = (LAMBDA x: inf_sum(powerseq(a,x)))


     Inf_inf_m: LEMMA conv_powerseries?(a,m) IMPLIES
                       Inf_sum(m,a) = (LAMBDA x: inf_sum(m,powerseq(a,x)))



  %  ------ Convergent powerseries is absolutely convergent -----

     powerseries_abs_conv: LEMMA (FORALL (x: T): convergent?(powerseries(a)(x)))
                             IMPLIES
                          (FORALL (x: T): convergent?(series(abs(powerseq(a,x)))))

  %  ------ A few simple power series --------------------- -----

     simple(x): sequence[real] = (LAMBDA n: x^n/factorial(n))

     simple_0_conv: LEMMA T_pred(0) IMPLIES convergent?(series(simple(0)))   

     simple_conv: LEMMA convergent?(series(simple(x)))

     m1_conv: LEMMA abs(x) < 1 IMPLIES 
                        convergent?(powerseries((LAMBDA (n: nat): (-1) ^ n))(x))
   
  END power_series_conv

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 49, column 52) for  powerseries(a)(x)
      % expected type  (convergent?)
  Inf_sum_TCC1: OBLIGATION
    FORALL (a: (conv_powerseries?), x: T): convergent?(powerseries(a)(x));

  % Subtype TCC generated (at line 54, column 35) for  powerseries(a, m)(x)
      % expected type  (convergent?)
  Inf_sum_TCC2: OBLIGATION
    FORALL (m: nat, a: {a | conv_powerseries?(a, m)}, x: T):
      convergent?(powerseries(a, m)(x));

  % Subtype TCC generated (at line 63, column 53) for  powerseq(a, x)
      % expected type  (conv_series?)
  Inf_inf_TCC1: OBLIGATION
    FORALL (a: sequence[real]):
      conv_powerseries?(a) IMPLIES (FORALL (x): conv_series?(powerseq(a, x)));

  % Subtype TCC generated (at line 67, column 57) for  powerseq(a, x)
      % expected type  {s | conv_series?(s, m)}
  Inf_inf_m_TCC1: OBLIGATION
    FORALL (a: sequence[real], m: nat):
      conv_powerseries?(a, m) IMPLIES
       (FORALL (x): conv_series?(powerseq(a, x), m));

  % Subtype TCC generated (at line 79, column 44) for  n
      % expected type  {i: int | x /= 0 OR i >= 0}
  simple_TCC1: OBLIGATION FORALL (x: T, n): x /= 0 OR n >= 0;


body:
  power_series_derivseq[T: TYPE from real]: THEORY
  %----------------------------------------------------------------------------
  %
  % Term by term differentiation of power series:
  %
  %  		                      n
  %		                    ----
  %  series(deriv_powerseq(a, x)) =   \     k*a(k)*x^(k-1)
  %		                    /
  %		                    ----
  %		                    k = 0
  %
  %  		                     n-1
  %		                    ----
  %                               =   \     (k+1)*a(k+1)*x^k
  %		                    /
  %		                    ----
  %		                    k = 0
  %
  % The intention here is that one passes in the domain of convergence [T]
  % of the power series.  This will either be all of the reals or {x| -R < x < R}
  % where R is the range of convergence.  Most of the lemmas assume
  % convergence of the power series a: conv_powerseries?(a) =
  %     (FORALL (x: T): convergent?(powerseries(a)(x))) 
  %
  %
  % Author: Ricky W. Butler        10/2/00
  %
  % NOTES
  %  * Prelude restrictions on ^ [i.e. ^(r: real, i:{i:int | r /= 0 OR i >= 0}]
  %    lead to IF-THEN-ELSE on definition of "deriv_powerseq"
  %  * The alternate form: derivseq(a): (LAMBDA (k: nat): (k+1)*a(k+1))avoids
  %    the difficulty by shifting (i.e. starting with 2nd term)
  %  * These are shown to be equivalent in lemma "eriv_series_shift"
  %
  %----------------------------------------------------------------------------
  BEGIN
   
     ASSUMING  %% T is either "real" or a open ball of radius R about 0

       IMPORTING analysis@deriv_domain_def

       connected_domain : ASSUMPTION connected?[T]

       not_one_element : ASSUMPTION not_one_element?[T]

       open            : ASSUMPTION 
           FORALL (x : T) : EXISTS (delta : posreal): FORALL (y: real):
                              abs(x-y) < delta IMPLIES T_pred(y) 


      ball: ASSUMPTION FORALL (x: T): T_pred(x) IMPLIES T_pred(-x)

     ENDASSUMING


    
     IMPORTING power_series_conv[T], analysis@derivatives

     AUTO_REWRITE- abs_0
     AUTO_REWRITE- abs_nat

     x,x0: VAR T
     k,n: VAR nat
     a: VAR sequence[real]
     t: VAR real

     epsilon: VAR posreal


     deriv_powerseq(a,x): sequence[real] = (LAMBDA k: IF k = 0 THEN 0
                                                      ELSIF k = 1 THEN a(1)
                                                      ELSE  k*a(k)*x^(k-1)
                                                      ENDIF)

  %  -------- term by term derivative is  convergent ------------------------

     deriv_powerseries_conv: THEOREM    % Rosenlicht page 152
                            conv_powerseries?(a) IMPLIES
                (FORALL (x: T): convergent?(series(deriv_powerseq(a, x))))



  % ----------- alternate form: starting with term 2 via shifting ------------


     derivseq(a): sequence[real] = (LAMBDA (k: nat): (k+1)*a(k+1))


     derivseq_conv: LEMMA conv_powerseries?(a) IMPLIES
                            convergent?(series(powerseq(derivseq(a),x)))

     deriv_series_shift: LEMMA conv_powerseries?(a) IMPLIES
                      limit(series(deriv_powerseq(a,x))) =
                           limit(series(powerseq(derivseq(a),x)))

     conv_derivseq: LEMMA conv_powerseries?(a) IMPLIES
                             conv_powerseries?[T](derivseq(a))


  %  ------ term by term differentiation of power sequence --------
     
     deriv_powerseq_lem: LEMMA derivable?[T](LAMBDA x: powerseq(a, x)(n)) AND
                               deriv[T](LAMBDA x: powerseq(a, x)(n)) =
                                  (LAMBDA x: deriv_powerseq(a,x)(n))

     sigma_power_derivable: LEMMA derivable?[T](LAMBDA x: sigma(0,n,powerseq(a,x)))


  %  ------ finite sum of power sequence ------

     deriv_sigma_power: LEMMA deriv[T](LAMBDA x: sigma(0, n, powerseq(a, x))) =
                                 (LAMBDA x: sigma(0, n, deriv_powerseq(a,x)))


     deriv_sigma_power_conv: LEMMA  conv_powerseries?(a) IMPLIES       
             convergent?(LAMBDA (n: nat):
                         deriv[T](LAMBDA x: sigma(0, n, powerseq(a, x)))(x))


     deriv_conv_prep: LEMMA conv_powerseries?(a) IMPLIES       
              convergent?(LAMBDA (n: nat): sigma(0, n, deriv_powerseq(a,x)))

  %  x_to_n_continuous: LEMMA continuous(LAMBDA x: x^n) %% moved to analysis lib

     deriv_powerseq_cont: LEMMA 
             continuous?(LAMBDA x: sigma(0,n,deriv_powerseq(a,x)))

     lim_deriv_alt: LEMMA conv_powerseries?(a) IMPLIES
                            limit(series(deriv_powerseq(a,x))) =
                            limit(series(deriv_powerseq(a,x),1))


  END power_series_derivseq

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 58, column 13) for  power_series_conv[T]
      % generated from assumption power_series_conv.not_one_element
  IMP_power_series_conv_TCC1: OBLIGATION not_one_element?[T];

  % Assuming TCC generated (at line 58, column 13) for  power_series_conv[T]
      % generated from assumption power_series_conv.deriv_domain
  IMP_power_series_conv_TCC2: OBLIGATION deriv_domain?[T];

  % Assuming TCC generated (at line 58, column 13) for  power_series_conv[T]
      % generated from assumption power_series_conv.open
  IMP_power_series_conv_TCC3: OBLIGATION
    FORALL (x: T):
      EXISTS (delta: posreal):
        FORALL (y: real): abs(x - y) < delta IMPLIES T_pred(y);

  % Subtype TCC generated (at line 73, column 68) for  (k - 1)
      % expected type  {i: int | x /= 0 OR i >= 0}
  deriv_powerseq_TCC1: OBLIGATION
    FORALL (x: T, k): NOT k = 1 AND NOT k = 0 IMPLIES x /= 0 OR (k - 1) >= 0;

  % Subtype TCC generated (at line 94, column 26) for
      % series(deriv_powerseq(a, x))
      % expected type  (convergent?)
  deriv_series_shift_TCC1: OBLIGATION
    FORALL (a: sequence[real], x: T):
      conv_powerseries?(a) IMPLIES convergent?(series(deriv_powerseq(a, x)));

  % Subtype TCC generated (at line 95, column 31) for
      % series(powerseq(derivseq(a), x))
      % expected type  (convergent?)
  deriv_series_shift_TCC2: OBLIGATION
    FORALL (a: sequence[real], x: T):
      conv_powerseries?(a) IMPLIES
       convergent?(series(powerseq(derivseq(a), x)));

  % Subtype TCC generated (at line 107, column 64) for  n
      % expected type  T_high[nat]
  sigma_power_derivable_TCC1: OBLIGATION
    FORALL (n: nat, x): n >= 0 OR (EXISTS (j: nat): n <= j);

  % Subtype TCC generated (at line 112, column 37) for
      % LAMBDA x: sigma(0, n, powerseq(a, x))
      % expected type  deriv_fun[T]
  deriv_sigma_power_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat):
      derivable?[T](LAMBDA x: sigma[nat](0, n, powerseq(a, x)));

  % Subtype TCC generated (at line 122, column 50) for  n
      % expected type  T_high[nat]
  deriv_conv_prep_TCC1: OBLIGATION
    FORALL (a: sequence[real]):
      conv_powerseries?(a) IMPLIES
       (FORALL (n: nat): n >= 0 OR (EXISTS (j: nat): n <= j));

  % Subtype TCC generated (at line 131, column 32) for
      % series(deriv_powerseq(a, x), 1)
      % expected type  (convergent?)
  lim_deriv_alt_TCC1: OBLIGATION
    FORALL (a: sequence[real], x: T):
      conv_powerseries?(a) IMPLIES
       convergent?(series(deriv_powerseq(a, x), 1));


body:
  power_series_deriv_scaf[T: TYPE from real]: THEORY
  %----------------------------------------------------------------------------
  %
  % Term by term differentiation of power series
  %
  % The intention here is that one passes in the domain of convergence [T]
  % of the power series.  This will either be all of the reals or {x| -R < x < R}
  % where R is the range of convergence
  %
  % Author: Ricky W. Butler        7/23/04
  %
  %
  %----------------------------------------------------------------------------
  BEGIN
   
     ASSUMING  %% T is either "real" or a open ball of radius R about 0

       IMPORTING analysis@deriv_domain_def

       connected_domain : ASSUMPTION connected?[T]

       not_one_element : ASSUMPTION not_one_element?[T]

       open            : ASSUMPTION 
           FORALL (x : T) : EXISTS (delta : posreal): FORALL (y: real):
                              abs(x-y) < delta IMPLIES T_pred(y) 


      ball: ASSUMPTION FORALL (x: T): T_pred(x) IMPLIES T_pred(-x)

     ENDASSUMING

     deriv_domain: LEMMA deriv_domain?[T]

     x,x0,xp: VAR T
     k,n: VAR nat
     a,b: VAR sequence[real]
     t: VAR real
     epsilon: VAR posreal
     m: VAR nat

     IMPORTING power_series_derivseq[T], analysis@taylors

     AUTO_REWRITE- abs_0
     AUTO_REWRITE- abs_nat

     GET_tk_prep: LEMMA FORALL (x: T,h:(A(x)),k: posnat): 
                        nonempty?[between[T](x, x + h)]
                             ({tk: between[T](x, x + h) |
                                ((x + h) ^ k - x ^ k) / h = k * tk ^ (k - 1)})


     GET_tk(x: T,h:(A(x)),k: posnat): {tk: between[T](x,x+h) | 
                           ((x+h)^k - x^k)/h = k*tk^(k-1)}


     Gseq(a,x,(h:(A(x))))(k): real = IF k < 2 THEN k*a(k) ELSE
                                       k*a(k)*(GET_tk(x,h,k)^(k-1) - x^(k-1))
                                     ENDIF


     conv_scaf0: LEMMA conv_powerseries?(a) IMPLIES 
                      convergent?(series(LAMBDA k: IF k < 2 THEN 0
                                      ELSE abs(k) * abs(k - 1) * abs(a(k)) *
                                       abs(x^(k - 2))
                                       ENDIF))



     A2seq(a,x,(xp:{xx:T | xx /= 0} ))(k): real = 
                                    LET ALPH = max(abs(x), abs(xp)) IN
                                    IF k < 2 THEN k ELSE
                                       abs(k)*abs(k-1)*abs(a(k)*ALPH^(k - 2))
                                    ENDIF

     fseq(a)(n): real = (1+n)*(2+n)*a(2+n)

     A2_conv_scaf: LEMMA abs(powerseq(a, x)) = powerseq(abs(a),abs(x))

     A2_conv: LEMMA  xp /= 0 AND 
                     conv_powerseries?(a)
                     IMPLIES 
              convergent?(series(A2seq(a,x,xp),2))


     delta: VAR posreal


     Gseq_conv: LEMMA conv_powerseries?(a) IMPLIES FORALL (h:(A(x))): 
                                         conv_series?(Gseq(a, x, h), 2)

     abs_Gseq_conv: LEMMA conv_powerseries?(a) IMPLIES FORALL (h:(A(x))): 
                                         conv_series?(abs(Gseq(a, x, h)), 2)

     inf_sum_Gseq_abs: LEMMA conv_powerseries?(a) IMPLIES FORALL (h:(A(x))): 
                             abs(inf_sum(2, Gseq(a, x, h))) <=
                                  inf_sum(2, abs(Gseq(a, x, h)))

     conv_scaf2: LEMMA conv_powerseries?(a) IMPLIES
                       FORALL (h:(A(x))): convergent?(series((LAMBDA k:
                             IF k < 2 THEN k * a(k)
                             ELSE k * a(k) * GET_tk(x, h, k) ^ (k - 1)
                             ENDIF),
                          1))


  %    conv_scaf1: LEMMA conv_powerseries?(a) IMPLIES
  %                      FORALL (h:(A(x))): convergent?(series((LAMBDA (k: nat):
  %                            IF k = 0 THEN 0
  %                            ELSE a(k) * ((x + h) ^ k - x ^ k)
  %                            ENDIF)))

     conv_scaf1: LEMMA conv_powerseries?(a) IMPLIES
                       FORALL (h:(A(x))): convergent?(series((LAMBDA (k: nat):
                               a(k) * ((x + h) ^ k - x ^ k)
                             )))



     conv_scaf3: LEMMA conv_powerseries?(a) IMPLIES
                       FORALL (h:(A(x))):  conv_series?((LAMBDA k:
                        a(k) * (((x + h) ^ k - x ^ k) / h)),
                     1)


     limit_eq_rew: LEMMA convergent?(a) AND convergent?(b) AND a = b 
                       IMPLIES limit(a)  = limit(b) 

  END power_series_deriv_scaf

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 42, column 13) for
      % power_series_derivseq[T]
      % generated from assumption power_series_derivseq.connected_domain
  IMP_power_series_derivseq_TCC1: OBLIGATION connected?[T];

  % Assuming TCC generated (at line 42, column 13) for
      % power_series_derivseq[T]
      % generated from assumption power_series_derivseq.not_one_element
  IMP_power_series_derivseq_TCC2: OBLIGATION not_one_element?[T];

  % Assuming TCC generated (at line 42, column 13) for
      % power_series_derivseq[T]
      % generated from assumption power_series_derivseq.open
  IMP_power_series_derivseq_TCC3: OBLIGATION
    FORALL (x: T):
      EXISTS (delta: posreal):
        FORALL (y: real): abs(x - y) < delta IMPLIES T_pred(y);

  % Assuming TCC generated (at line 42, column 13) for
      % power_series_derivseq[T]
      % generated from assumption power_series_derivseq.ball
  IMP_power_series_derivseq_TCC4: OBLIGATION
    FORALL (x: T): TRUE IMPLIES T_pred(-x);

  % Subtype TCC generated (at line 50, column 41) for  k
      % expected type  {i: int | NOT h + x = 0 OR i >= 0}
  GET_tk_prep_TCC1: OBLIGATION
    FORALL (x: T, h: (A[T](x)), k: posnat, tk: between[T](x, x + h)):
      NOT h + x = 0 OR k >= 0;

  % Subtype TCC generated (at line 50, column 49) for  k
      % expected type  {i: int | x /= 0 OR i >= 0}
  GET_tk_prep_TCC2: OBLIGATION
    FORALL (x: T, h: (A[T](x)), k: posnat, tk: between[T](x, x + h)):
      x /= 0 OR k >= 0;

  % Subtype TCC generated (at line 50, column 68) for  (k - 1)
      % expected type  {i: int | tk /= 0 OR i >= 0}
  GET_tk_prep_TCC3: OBLIGATION
    FORALL (x: T, h: (A[T](x)), k: posnat, tk: between[T](x, x + h)):
      tk /= 0 OR (k - 1) >= 0;

  % Existence TCC generated (at line 53, column 3) for
      % GET_tk(x: T, h: (A(x)), k: posnat):
      %       {tk: between[T](x, x + h) |
      %                ((x + h) ^ k - x ^ k) / h = k * tk ^ (k - 1)}
  GET_tk_TCC1: OBLIGATION
    EXISTS (x1:
              [d: [x: T, (A[T](x)), posnat] ->
                 {tk: between[T](d`1, d`1 + d`2) |
                          ((d`1 + d`2) ^ d`3 - d`1 ^ d`3) / d`2 =
                           d`3 * tk ^ (d`3 - 1)}]):
      TRUE;

  % Subtype TCC generated (at line 58, column 56) for  k
      % expected type  posnat
  Gseq_TCC1: OBLIGATION
    FORALL (x: T, (h: (A[T](x))), k: nat): NOT k < 2 IMPLIES k > 0;

  % Subtype TCC generated (at line 58, column 60) for  (k - 1)
      % expected type  {i: int | GET_tk(x, h, k) /= 0 OR i >= 0}
  Gseq_TCC2: OBLIGATION
    FORALL (x: T, (h: (A[T](x))), k: nat):
      NOT k < 2 IMPLIES GET_tk(x, h, k) /= 0 OR (k - 1) >= 0;

  % Subtype TCC generated (at line 58, column 70) for  (k - 1)
      % expected type  {i: int | x /= 0 OR i >= 0}
  Gseq_TCC3: OBLIGATION
    FORALL (x: T, (h: (A[T](x))), k: nat):
      NOT k < 2 IMPLIES x /= 0 OR (k - 1) >= 0;

  % Subtype TCC generated (at line 65, column 44) for  (k - 2)
      % expected type  {i: int | x /= 0 OR i >= 0}
  conv_scaf0_TCC1: OBLIGATION
    FORALL (a: sequence[real], x: T):
      conv_powerseries?(a) IMPLIES
       (FORALL (k): NOT k < 2 IMPLIES x /= 0 OR (k - 2) >= 0);

  % Subtype TCC generated (at line 73, column 68) for  (k - 2)
      % expected type  {i: int | ALPH /= 0 OR i >= 0}
  A2seq_TCC1: OBLIGATION
    FORALL (x: T, (xp: {xx: T | xx /= 0}), k: nat,
            ALPH: {z: nonneg_real | z >= abs(x) AND z >= abs(xp)}):
      NOT k < 2 AND ALPH = max(abs(x), abs(xp)) IMPLIES
       ALPH /= 0 OR (k - 2) >= 0;

  % Subtype TCC generated (at line 96, column 42) for  Gseq(a, x, h)
      % expected type  {s | conv_series?(s, 2)}
  inf_sum_Gseq_abs_TCC1: OBLIGATION
    FORALL (a: sequence[real], x: T):
      conv_powerseries?(a) IMPLIES
       (FORALL (h: (A[T](x))): conv_series?(Gseq(a, x, h), 2));

  % Subtype TCC generated (at line 97, column 43) for  abs(Gseq(a, x, h))
      % expected type  {s | conv_series?(s, 2)}
  inf_sum_Gseq_abs_TCC2: OBLIGATION
    FORALL (a: sequence[real], x: T):
      conv_powerseries?(a) IMPLIES
       (FORALL (h: (A[T](x))): conv_series?(abs(Gseq(a, x, h)), 2));

  % Subtype TCC generated (at line 115, column 47) for  k
      % expected type  {i: int | NOT h + x = 0 OR i >= 0}
  conv_scaf1_TCC1: OBLIGATION
    FORALL (a: sequence[real], x: T):
      conv_powerseries?(a) IMPLIES
       (FORALL (h: (A[T](x)), k: nat): NOT h + x = 0 OR k >= 0);

  % Subtype TCC generated (at line 115, column 55) for  k
      % expected type  {i: int | x /= 0 OR i >= 0}
  conv_scaf1_TCC2: OBLIGATION
    FORALL (a: sequence[real], x: T):
      conv_powerseries?(a) IMPLIES
       (FORALL (h: (A[T](x)), k: nat): x /= 0 OR k >= 0);


body:
  power_series_deriv[T: TYPE from real]: THEORY
  %----------------------------------------------------------------------------
  %
  % Term by term differentiation of power series:
  %
  %  		                      n
  %		                    ----
  %  series(deriv_powerseq(a, x)) =   \     k*a(k)*x^(k-1)
  %		                    /
  %		                    ----
  %		                    k = 0
  %
  %  		                     n-1
  %		                    ----
  %                               =   \     (k+1)*a(k+1)*x^k
  %		                    /
  %		                    ----
  %		                    k = 0
  %
  % The intention here is that one passes in the domain of convergence [T]
  % of the power series.  This will either be all of the reals or {x| -R < x < R}
  % where R is the range of convergence.  Most of the lemmas assume
  % convergence of the power series a: conv_powerseries?(a) =
  %     (FORALL (x: T): convergent?(powerseries(a)(x))) 
  %
  %
  % Author: Ricky W. Butler        10/2/00
  %
  % NOTES
  %  * Prelude restrictions on ^ [i.e. ^(r: real, i:{i:int | r /= 0 OR i >= 0}]
  %    lead to IF-THEN-ELSE on definition of "deriv_powerseq"
  %  * The alternate form: derivseq(a): (LAMBDA (k: nat): (k+1)*a(k+1))avoids
  %    the difficulty by shifting (i.e. starting with 2nd term)
  %  * These are shown to be equivalent in lemma "deriv_series_shift"
  %
  %----------------------------------------------------------------------------
  BEGIN
   
     ASSUMING  %% T is either "real" or a open ball of radius R about 0
       IMPORTING analysis@deriv_domain_def

       connected_domain : ASSUMPTION connected?[T]

       not_one_element : ASSUMPTION not_one_element?[T]

       open            : ASSUMPTION 
           FORALL (x : T) : EXISTS (delta : posreal): FORALL (y: real):
                              abs(x-y) < delta IMPLIES T_pred(y) 


      ball: ASSUMPTION FORALL (x: T): T_pred(x) IMPLIES T_pred(-x)

     ENDASSUMING

    
     deriv_domain: LEMMA  deriv_domain?[T]

     x,xp, x0: VAR T
     k,n: VAR nat
     a: VAR sequence[real]
     t: VAR real
     epsilon: VAR posreal

  %  Derivative of a infinite power series is the term-by-term derivative

     IMPORTING power_series_deriv_scaf[T], power_series_derivseq[T],  analysis@taylors

     AUTO_REWRITE- abs_0
     AUTO_REWRITE- abs_nat


  %   deriv_powerseq(a,x): sequence[real] = (LAMBDA k: IF k = 0 THEN 0
  %                                                    ELSIF k = 1 THEN a(1)
  %                                                    ELSE  k*a(k)*x^(k-1)
  %                                                    ENDIF)
  %
  %   derivseq(a): sequence[real] = (LAMBDA (k: nat): (k+1)*a(k+1))



     powerseries_deriv: THEOREM   conv_powerseries?(a) IMPLIES     
         derivable?[T](LAMBDA (xx: T): limit(powerseries(a)(xx))) AND
         (
            LET f = (LAMBDA x: limit(powerseries(a)(x))) IN         
            LET g = (LAMBDA x: limit(series(deriv_powerseq(a,x)))) IN 
                     g = deriv[T](f)  )




     powerseries_derivable: THEOREM conv_powerseries?(a) IMPLIES   
                        derivable?[T](LAMBDA (xx: T): limit(powerseries(a)(xx))) 

     powerseries_cont: COROLLARY conv_powerseries?(a) IMPLIES   
                           continuous?(LAMBDA (xx: T): limit(powerseries(a)(xx))) 


     Inf_sum_derivable: THEOREM conv_powerseries?(a) IMPLIES   
                                   derivable?[T](Inf_sum(a)) 

     deriv_Inf_sum: THEOREM conv_powerseries?(a) IMPLIES 
               deriv[T](Inf_sum(a)) = Inf_sum(derivseq(a))


  %  ----- infinite power series is infinitely derivable ------


     deriv_Inf_sum_derivable: THEOREM conv_powerseries?(a) IMPLIES     
                                        derivable?[T](deriv[T](Inf_sum(a)))

     IMPORTING analysis@nth_derivatives

     Inf_sum_derivable_n_times: LEMMA conv_powerseries?(a) IMPLIES     
                                         derivable_n_times?(Inf_sum(a),n)


  END power_series_deriv

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 66, column 13) for
      % power_series_deriv_scaf[T]
      % generated from assumption power_series_deriv_scaf.connected_domain
  IMP_power_series_deriv_scaf_TCC1: OBLIGATION connected?[T];

  % Assuming TCC generated (at line 66, column 13) for
      % power_series_deriv_scaf[T]
      % generated from assumption power_series_deriv_scaf.not_one_element
  IMP_power_series_deriv_scaf_TCC2: OBLIGATION not_one_element?[T];

  % Assuming TCC generated (at line 66, column 13) for
      % power_series_deriv_scaf[T]
      % generated from assumption power_series_deriv_scaf.open
  IMP_power_series_deriv_scaf_TCC3: OBLIGATION
    FORALL (x: T):
      EXISTS (delta: posreal):
        FORALL (y: real): abs(x - y) < delta IMPLIES T_pred(y);

  % Assuming TCC generated (at line 66, column 13) for
      % power_series_deriv_scaf[T]
      % generated from assumption power_series_deriv_scaf.ball
  IMP_power_series_deriv_scaf_TCC4: OBLIGATION
    FORALL (x: T): TRUE IMPLIES T_pred(-x);

  % Subtype TCC generated (at line 82, column 43) for  powerseries(a)(xx)
      % expected type  (convergent?)
  powerseries_deriv_TCC1: OBLIGATION
    FORALL (a: sequence[real]):
      conv_powerseries?(a) IMPLIES
       (FORALL (xx: T): convergent?(powerseries(a)(xx)));

  % Assuming TCC generated (at line 24, column 4) for  analysis@derivatives[T]
      % generated from assumption derivatives.deriv_domain
  powerseries_deriv_TCC2: OBLIGATION
    FORALL (a: sequence[real]): conv_powerseries?(a) IMPLIES deriv_domain?[T];

  % Subtype TCC generated (at line 85, column 35) for
      % series(deriv_powerseq(a, x))
      % expected type  (convergent?)
  powerseries_deriv_TCC3: OBLIGATION
    FORALL (a: sequence[real]):
      conv_powerseries?(a) AND
       derivable?[T](LAMBDA (xx: T): limit(powerseries(a)(xx)))
       IMPLIES
       (FORALL (f: [T -> real]):
          (f = (LAMBDA x: limit(powerseries(a)(x)))) IMPLIES
           (FORALL (x1): convergent?(series(deriv_powerseq[T](a, x1)))));

  % Subtype TCC generated (at line 86, column 32) for  f
      % expected type  deriv_fun[T]
  powerseries_deriv_TCC4: OBLIGATION
    FORALL (a: sequence[real]):
      conv_powerseries?(a) AND
       derivable?[T](LAMBDA (xx: T): limit(powerseries(a)(xx)))
       IMPLIES
       (FORALL (f: [T -> real]):
          (f = (LAMBDA x: limit(powerseries(a)(x)))) IMPLIES
           (FORALL (g: [T -> real]):
              (g = (LAMBDA x: limit(series(deriv_powerseq(a, x))))) IMPLIES
               derivable?[T](f)));

  % Subtype TCC generated (at line 102, column 22) for  Inf_sum(a)
      % expected type  deriv_fun[T]
  deriv_Inf_sum_TCC1: OBLIGATION
    FORALL (a: sequence[real]):
      conv_powerseries?(a) IMPLIES derivable?[T](Inf_sum[T](a));

  % Subtype TCC generated (at line 102, column 44) for  derivseq(a)
      % expected type  (conv_powerseries?)
  deriv_Inf_sum_TCC2: OBLIGATION
    FORALL (a: sequence[real]):
      conv_powerseries?(a) IMPLIES conv_powerseries?[T](derivseq[T](a));


body:
  power_series_integ[T: TYPE+ from real]: THEORY
  %----------------------------------------------------------------------------
  %
  % Term by term integration of power series:
  %
  %  		                      n
  %		                    ----
  %  series(integ_powerseq(a, x)) =   \     a(k)*x^(k+1)/k+1
  %		                    /
  %		                    ----
  %		                    k = 0
  %
  %
  % The intention here is that one passes in the domain of convergence [T]
  % of the power series.  This will either be all of the reals or {x| -R < x < R}
  % where R is the range of convergence.  Most of the lemmas assume
  % convergence of the power series a: conv_powerseries?(a) =
  %     (FORALL (x: T): convergent?(powerseries(a)(x))) 
  %
  %
  % Author: Ricky W. Butler        10/2/04
  %
  % NOTES
  %  * Prelude restrictions on ^ [i.e. ^(r: real, i:{i:int | r /= 0 OR i >= 0}]
  %    lead to IF-THEN-ELSE on definition of "integ_powerseq"
  %  * The alternate form: integseq(a): (LAMBDA (k: nat): (k+1)*a(k+1))avoids
  %    the difficulty by shifting (i.e. starting with 2nd term)
  %  * These are shown to be equivalent in lemma "eriv_series_shift"
  %
  %  Author: Ricky W. Butler                NASA Langley Research Center
  %----------------------------------------------------------------------------
  BEGIN
   
     ASSUMING  %% T is either "real" or a open ball of radius R about 0
       IMPORTING analysis@deriv_domain_def

      connected_domain : ASSUMPTION connected?[T]

      not_one_element  : ASSUMPTION not_one_element?[T]

      open            : ASSUMPTION 
           FORALL (x : T) : EXISTS (delta : posreal): FORALL (y: real):
                              abs(x-y) < delta IMPLIES T_pred(y) 


      ball: ASSUMPTION FORALL (x: T): T_pred(x) IMPLIES T_pred(-x)

     ENDASSUMING

    
     x,xp, x0: VAR T
     k,n: VAR nat
     a: VAR sequence[real]
     t: VAR real

     epsilon: VAR posreal


  %  Integative of a infinite power series is the term-by-term integative

     IMPORTING analysis@deriv_domain_def

     deriv_domain: LEMMA deriv_domain?[T]

     IMPORTING power_series_conv[T], analysis@derivatives, analysis@taylors

     integseq(a): sequence[real] = (LAMBDA (k: nat): IF k = 0 THEN 0
                                                     ELSE a(k-1)/k ENDIF)


     integ_powerseq(a,x): sequence[real] = (LAMBDA k:  a(k)*x^(k+1)/(k+1))
                                               


  %  -------- term by term integration is  convergent ------------------------



     conv_integseq: LEMMA conv_powerseries?(a) IMPLIES % Salas Hille page 454
                             conv_powerseries?[T](integseq(a))


     integ_powerseries_conv: THEOREM    
                            conv_powerseries?(a) IMPLIES
                (FORALL (x: T): convergent?(series(integ_powerseq(a, x))))


     integseq_lim_shift: LEMMA conv_powerseries?(a) IMPLIES
                           (LAMBDA x: limit(series(powerseq(integseq(a), x)))) = 
                           (LAMBDA x: limit(series(integ_powerseq(a, x))))


     IMPORTING  power_series_deriv[T],
                analysis@integral[T],
                analysis@fundamental_theorem[T],
                analysis@indefinite_integral[T]


     powerseries_integrable?: LEMMA conv_powerseries?(a) IMPLIES
                               integrable?[T](LAMBDA x: limit(powerseries(a)(x)))



     powerseries_integral: THEOREM   conv_powerseries?(a) IMPLIES     
         (
            LET f = (LAMBDA x: limit(powerseries(a)(x))) IN         
            LET g = (LAMBDA x: limit(series(integ_powerseq(a,x)))) IN 
                     EXISTS (C: real): integral[T](f) = g + const_fun(C) )

     integral_powerseries: THEOREM   T_pred(0) AND conv_powerseries?(a) IMPLIES 
            LET f = (LAMBDA x: limit(powerseries(a)(x))) IN 
                Integrable?(0,x,f) AND        
                Integral(0,x,f) = limit(series(integ_powerseq(a,x)))

  END power_series_integ

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 65, column 13) for  power_series_conv[T]
      % generated from assumption power_series_conv.not_one_element
  IMP_power_series_conv_TCC1: OBLIGATION not_one_element?[T];

  % Assuming TCC generated (at line 65, column 13) for  power_series_conv[T]
      % generated from assumption power_series_conv.deriv_domain
  IMP_power_series_conv_TCC2: OBLIGATION deriv_domain?[T];

  % Assuming TCC generated (at line 65, column 13) for  power_series_conv[T]
      % generated from assumption power_series_conv.open
  IMP_power_series_conv_TCC3: OBLIGATION
    FORALL (x: T):
      EXISTS (delta: posreal):
        FORALL (y: real): abs(x - y) < delta IMPLIES T_pred(y);

  % Subtype TCC generated (at line 68, column 58) for  k - 1
      % expected type  nat
  integseq_TCC1: OBLIGATION FORALL (k: nat): NOT k = 0 IMPLIES k - 1 >= 0;

  % Subtype TCC generated (at line 68, column 63) for  k
      % expected type  nznum
  integseq_TCC2: OBLIGATION FORALL (k: nat): NOT k = 0 IMPLIES k /= 0;

  % Subtype TCC generated (at line 71, column 61) for  (k + 1)
      % expected type  {i: int | x /= 0 OR i >= 0}
  integ_powerseq_TCC1: OBLIGATION FORALL (x: T, k): x /= 0 OR (k + 1) >= 0;

  % Subtype TCC generated (at line 89, column 42) for
      % series(powerseq(integseq(a), x))
      % expected type  (convergent?)
  integseq_lim_shift_TCC1: OBLIGATION
    FORALL (a: sequence[real]):
      conv_powerseries?(a) IMPLIES
       (FORALL (x): convergent?(series(powerseq(integseq(a), x))));

  % Subtype TCC generated (at line 90, column 42) for
      % series(integ_powerseq(a, x))
      % expected type  (convergent?)
  integseq_lim_shift_TCC2: OBLIGATION
    FORALL (a: sequence[real]):
      conv_powerseries?(a) IMPLIES
       (FORALL (x): convergent?(series(integ_powerseq(a, x))));

  % Assuming TCC generated (at line 93, column 14) for  power_series_deriv[T]
      % generated from assumption power_series_deriv.connected_domain
  IMP_power_series_deriv_TCC1: OBLIGATION connected?[T];

  % Assuming TCC generated (at line 93, column 14) for  power_series_deriv[T]
      % generated from assumption power_series_deriv.ball
  IMP_power_series_deriv_TCC2: OBLIGATION
    FORALL (x: T): TRUE IMPLIES T_pred(-x);

  % Subtype TCC generated (at line 100, column 60) for  powerseries(a)(x)
      % expected type  (convergent?)
  powerseries_integrable?_TCC1: OBLIGATION
    FORALL (a: sequence[real]):
      conv_powerseries?(a) IMPLIES
       (FORALL (x): convergent?(powerseries(a)(x)));

  % Subtype TCC generated (at line 108, column 49) for  f
      % expected type  f: integrable_fun[T]
  powerseries_integral_TCC1: OBLIGATION
    FORALL (a: sequence[real]):
      conv_powerseries?(a) IMPLIES
       (FORALL (f: [T -> real]):
          (f = (LAMBDA x: limit(powerseries(a)(x)))) IMPLIES
           (FORALL (g: [T -> real]):
              (g = (LAMBDA x: limit(series(integ_powerseq(a, x))))) IMPLIES
               integrable?[T](f)));


body:
  taylor_series[T: TYPE+ from real]: THEORY
  %----------------------------------------------------------------------------
  %
  %  		                     n-1
  %		                    ----
  %                               =   \     (k+1)*a(k+1)*x^k
  %		                    /
  %		                    ----
  %		                    k = 0
  %
  % The intention here is that one passes in the domain of convergence [T]
  % of the power series.  This will either be all of the reals or {x| -R < x < R}
  % where R is the range of convergence.  Most of the lemmas assume
  % convergence of the power series a: conv_powerseries?(a) =
  %     (FORALL (x: T): convergent?(powerseries(a)(x))) 
  %
  %
  % Author: Ricky W. Butler        7/8/2004
  %
  %
  %----------------------------------------------------------------------------
  BEGIN
   
     ASSUMING  %% T is either "real" or a open ball of radius R about 0
       IMPORTING analysis@deriv_domain_def

       connected_domain : ASSUMPTION connected?[T]

       not_one_element : ASSUMPTION not_one_element?[T]

       open            : ASSUMPTION 
           FORALL (x : T) : EXISTS (delta : posreal): FORALL (y: real):
                              abs(x-y) < delta IMPLIES T_pred(y) 

       ball: ASSUMPTION FORALL (x: T): T_pred(x) IMPLIES T_pred(-x)

     ENDASSUMING


     T_pred_0: LEMMA T_pred(0)
    
     IMPORTING analysis@deriv_domain_def, power_series_deriv[T]

     deriv_domain: LEMMA  deriv_domain?[T]


     x,x0: VAR T
     k,n: VAR nat
     a: VAR sequence[real]
     t: VAR real

     epsilon: VAR posreal

     f: VAR [T -> real]

     Inf_sum_0: LEMMA conv_powerseries?[T](a) IMPLIES
                          Inf_sum(a)(0) = a(0) 

     nderivseq(n,a): sequence[real] = 
               (LAMBDA (k: nat): factorial(k+n)/factorial(k)*a(k+n))


     nderivseq_lem: LEMMA nderivseq(n+1, a) =
                          nderivseq(n,derivseq(a))


     conv_nderivseq: LEMMA conv_powerseries?(a) IMPLIES
                               conv_powerseries?[T](nderivseq(n, a))

     Inf_sum_derivable_n_times: LEMMA  conv_powerseries?(a) IMPLIES
                                   derivable_n_times?[T](Inf_sum[T](a), n)


     nderiv_Inf_sum: THEOREM conv_powerseries?(a) IMPLIES 
                         nderiv[T](n,Inf_sum(a)) = Inf_sum(nderivseq(n,a))


     Taylor_expansion: LEMMA FORALL n: conv_powerseries?[T](a) AND
                                       f = Inf_sum(a) 
                                IMPLIES derivable_n_times?(f,n) AND
                                        factorial(n)*a(n) = nderiv(n,f)(0)


     Taylor_seq(f:(inf_deriv_fun?[T]))(n): real = 
                                          nderiv(n,f)(0)/factorial(n) 
    
     Taylor_seq_term: LEMMA inf_deriv_fun?(f) IMPLIES
                           (LAMBDA n: IF n = 0 THEN f(0) 
                                      ELSE Taylor_seq(f)(n)*x^n 
                                      ENDIF) = Taylor_term(f,0,x)

  %  ---- GET_C returns the const c from Taylor's Theorem -----

     GET_C(f:(inf_deriv_fun?[T]), x: T, k: nat): {c: between[T](0, x) |
                     powerseries(Taylor_seq(f))(x)(k) =
                          f(x) - Taylor_rem(k, f, 0, x, c)}

     is_taylor_prep: LEMMA inf_deriv_fun?(f) AND
                        (FORALL (x:T):
                          convergent?(LAMBDA n: Taylor_rem(n,f,0,x,GET_C(f,x,n))))
                       IMPLIES
                          conv_powerseries?[T](Taylor_seq(f))


     is_taylor: LEMMA  inf_deriv_fun?(f) AND
                        (FORALL (x:T):
                       convergence(LAMBDA n: Taylor_rem(n,f,0,x,GET_C(f,x,n)),0))
                    IMPLIES
                          f = Inf_sum(Taylor_seq(f))

  END taylor_series

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 42, column 40) for  power_series_deriv[T]
      % generated from assumption power_series_deriv.connected_domain
  IMP_power_series_deriv_TCC1: OBLIGATION connected?[T];

  % Assuming TCC generated (at line 42, column 40) for  power_series_deriv[T]
      % generated from assumption power_series_deriv.not_one_element
  IMP_power_series_deriv_TCC2: OBLIGATION not_one_element?[T];

  % Assuming TCC generated (at line 42, column 40) for  power_series_deriv[T]
      % generated from assumption power_series_deriv.open
  IMP_power_series_deriv_TCC3: OBLIGATION
    FORALL (x: T):
      EXISTS (delta: posreal):
        FORALL (y: real): abs(x - y) < delta IMPLIES T_pred(y);

  % Assuming TCC generated (at line 42, column 40) for  power_series_deriv[T]
      % generated from assumption power_series_deriv.ball
  IMP_power_series_deriv_TCC4: OBLIGATION
    FORALL (x: T): TRUE IMPLIES T_pred(-x);

  % Subtype TCC generated (at line 57, column 35) for  0
      % expected type  T
  Inf_sum_0_TCC1: OBLIGATION
    FORALL (a: sequence[real]): conv_powerseries?[T](a) IMPLIES T_pred(0);

  % Assuming TCC generated (at line 22, column 3) for
      % analysis@nth_derivatives[T]
      % generated from assumption nth_derivatives.deriv_domain
  Inf_sum_derivable_n_times_TCC1: OBLIGATION
    FORALL (a: sequence[real]): conv_powerseries?(a) IMPLIES deriv_domain?[T];

  % Subtype TCC generated (at line 75, column 35) for  Inf_sum(a)
      % expected type  nderiv_fun[T](n)
  nderiv_Inf_sum_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat):
      conv_powerseries?(a) IMPLIES derivable_n_times?[T](Inf_sum[T](a), n);

  % Subtype TCC generated (at line 75, column 57) for  nderivseq(n, a)
      % expected type  (conv_powerseries?)
  nderiv_Inf_sum_TCC2: OBLIGATION
    FORALL (a: sequence[real], n: nat):
      conv_powerseries?(a) IMPLIES conv_powerseries?[T](nderivseq(n, a));

  % Subtype TCC generated (at line 85, column 52) for  0
      % expected type  T
  Taylor_seq_TCC1: OBLIGATION FORALL (f: (inf_deriv_fun?[T])): T_pred(0);

  % Subtype TCC generated (at line 85, column 49) for  f
      % expected type  nderiv_fun[T](n)
  Taylor_seq_TCC2: OBLIGATION
    FORALL (f: (inf_deriv_fun?[T]), n: nat): derivable_n_times?[T](f, n);

  % Assuming TCC generated (at line 27, column 26) for
      % analysis@nth_derivatives[T]
      % generated from assumption nth_derivatives.deriv_domain
  Taylor_seq_TCC3: OBLIGATION
    FORALL (f: (inf_deriv_fun?[T])): deriv_domain?[T];

  % Subtype TCC generated (at line 88, column 52) for  0
      % expected type  T
  Taylor_seq_term_TCC1: OBLIGATION
    FORALL (f: [T -> real]):
      inf_deriv_fun?(f) IMPLIES (FORALL (n): n = 0 IMPLIES T_pred(0));

  % Subtype TCC generated (at line 89, column 60) for  n
      % expected type  {i: int | x /= 0 OR i >= 0}
  Taylor_seq_term_TCC2: OBLIGATION
    FORALL (f: [T -> real], x: T):
      inf_deriv_fun?(f) IMPLIES
       (FORALL (n): NOT n = 0 IMPLIES x /= 0 OR n >= 0);

  % Subtype TCC generated (at line 90, column 59) for  0
      % expected type  T
  Taylor_seq_term_TCC3: OBLIGATION
    FORALL (f: [T -> real]): inf_deriv_fun?(f) IMPLIES T_pred(0);

  % Subtype TCC generated (at line 96, column 45) for  f
      % expected type  nderiv_fun[T](1 + k)
  GET_C_TCC1: OBLIGATION
    FORALL (f: (inf_deriv_fun?[T]), k: nat, x: T, c: between[T](0, x)):
      derivable_n_times?[T](f, 1 + k);

  % Subtype TCC generated (at line 96, column 48) for  0
      % expected type  T
  GET_C_TCC2: OBLIGATION FORALL (x: T, c: between[T](0, x)): T_pred(0);

  % Existence TCC generated (at line 94, column 3) for
      % GET_C(f: (inf_deriv_fun?[T]), x: T, k: nat):
      %       {c: between[T](0, x) |
      %                powerseries(Taylor_seq(f))(x)(k) =
      %                 f(x) - Taylor_rem(k, f, 0, x, c)}
  GET_C_TCC3: OBLIGATION
    EXISTS (x1:
              [d: [(inf_deriv_fun?[T]), T, nat] ->
                 {c: between[T](0, d`2) |
                          powerseries(Taylor_seq(d`1))(d`2)(d`3) =
                           d`1(d`2) - Taylor_rem[T](d`3, d`1, 0, d`2, c)}]):
      TRUE;

  % Subtype TCC generated (at line 100, column 59) for  f
      % expected type  nderiv_fun[T](1 + n)
  is_taylor_prep_TCC1: OBLIGATION
    FORALL (f: [T -> real]):
      inf_deriv_fun?(f) IMPLIES (FORALL (n): derivable_n_times?[T](f, 1 + n));

  % Subtype TCC generated (at line 109, column 36) for  Taylor_seq(f)
      % expected type  (conv_powerseries?)
  is_taylor_TCC1: OBLIGATION
    FORALL (f: [T -> real]):
      (FORALL (x: T):
         convergence(LAMBDA n: Taylor_rem(n, f, 0, x, GET_C(f, x, n)), 0))
       AND inf_deriv_fun?(f)
       IMPLIES conv_powerseries?[T](Taylor_seq(f));


body:
  trig_fun: THEORY
  %----------------------------------------------------------------------------
  %
  % Definition of trigonometric functions
  %
  % Developed  by Ricky W. Butler      NASA Langley Research Center
  % 
  %      Version 1.0    last modified 10/02/00
  %
  %
  %----------------------------------------------------------------------------

  BEGIN

     IMPORTING power_series_conv, ints@factorial, analysis@deriv_domain

     AUTO_REWRITE- abs_0
     AUTO_REWRITE- abs_nat

     n: VAR nat
     x: VAR real

     c1,c2: VAR nat
     useful_prep: LEMMA convergent?(series(LAMBDA n: (abs(x))^n/factorial(n))) 


     altsign_prep: LEMMA (-1) ^ n = -1 OR (-1) ^ n = 1

     altsign(n: nat): {i: int | i = -1 OR i = 1} = IF even?(n) THEN (-1)^(n/2)
                                                   ELSE (-1)^((n-1)/2)
                                                   ENDIF

     abs_altsign: LEMMA abs(altsign(n)) = 1

     sin_coef(n): real = if even?(n) then 0 else altsign(n)/factorial(n) endif

     cos_coef(n): real = if even?(n) then altsign(n)/factorial(n) else 0 endif 


  %  ----- convergent?(powerseries(sin_coef)(x)) ----

     sin_conv: LEMMA conv_powerseries?[real](sin_coef) 
                           
     sin(x): real = inf_sum(powerseq(sin_coef,x))

  %  ----- convergent?(powerseries(cos_coef)(x)) ----

     cos_conv: LEMMA conv_powerseries?[real](cos_coef) 

     cos(x): real = inf_sum(powerseq(cos_coef,x))

     tan_domain: TYPE = {x: real | cos(x) /= 0}

     tan(x:tan_domain): real = sin(x)/cos(x)

     sin_0: LEMMA sin(0) = 0

     cos_0: LEMMA cos(0) = 1

      

  END trig_fun

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 24, column 60) for  n
      % expected type  {i: int | (abs(x)) /= 0 OR i >= 0}
  useful_prep_TCC1: OBLIGATION FORALL (x: real, n): (abs(x)) /= 0 OR n >= 0;

  % Subtype TCC generated (at line 29, column 72) for  (n / 2)
      % expected type  {i: int | TRUE}
  altsign_TCC1: OBLIGATION
    FORALL (n: nat): even?(n) IMPLIES integer_pred((n / 2));

  % Subtype TCC generated (at line 29, column 66) for  (-1) ^ (n / 2)
      % expected type  {i: int | i = -1 OR i = 1}
  altsign_TCC2: OBLIGATION
    FORALL (n: nat):
      even?(n) IMPLIES
       integer_pred((-1) ^ (n / 2)) AND
        ((-1) ^ (n / 2) = -1 OR (-1) ^ (n / 2) = 1);

  % Subtype TCC generated (at line 30, column 60) for  ((n - 1) / 2)
      % expected type  {i: int | TRUE}
  altsign_TCC3: OBLIGATION
    FORALL (n: nat): NOT even?(n) IMPLIES integer_pred(((n - 1) / 2));

  % Subtype TCC generated (at line 30, column 54) for  (-1) ^ ((n - 1) / 2)
      % expected type  {i: int | i = -1 OR i = 1}
  altsign_TCC4: OBLIGATION
    FORALL (n: nat):
      NOT even?(n) IMPLIES
       integer_pred((-1) ^ ((n - 1) / 2)) AND
        ((-1) ^ ((n - 1) / 2) = -1 OR (-1) ^ ((n - 1) / 2) = 1);

  % Assuming TCC generated (at line 27, column 5) for  power_series_conv[real]
      % generated from assumption power_series_conv.not_one_element
  sin_conv_TCC1: OBLIGATION not_one_element?[real];

  % Assuming TCC generated (at line 29, column 5) for  power_series_conv[real]
      % generated from assumption power_series_conv.deriv_domain
  sin_conv_TCC2: OBLIGATION deriv_domain?[real];

  % Assuming TCC generated (at line 31, column 5) for  power_series_conv[real]
      % generated from assumption power_series_conv.open
  sin_conv_TCC3: OBLIGATION
    FORALL (x: real): EXISTS (delta: posreal): FORALL (y: real): TRUE;

  % Subtype TCC generated (at line 44, column 26) for  powerseq(sin_coef, x)
      % expected type  (conv_series?)
  sin_TCC1: OBLIGATION FORALL (x: real): conv_series?(powerseq(sin_coef, x));

  % Subtype TCC generated (at line 50, column 26) for  powerseq(cos_coef, x)
      % expected type  (conv_series?)
  cos_TCC1: OBLIGATION FORALL (x: real): conv_series?(powerseq(cos_coef, x));

  % Subtype TCC generated (at line 54, column 36) for  cos(x)
      % expected type  nznum
  tan_TCC1: OBLIGATION FORALL (x: tan_domain): cos(x) /= 0;


body:
  trig_props: THEORY
  BEGIN

  %   analysis: LIBRARY "../analysis"

     IMPORTING power_series_deriv[real], 
               trig_fun, analysis@derivative_props, analysis@deriv_domain


     n: VAR nat
     x: VAR real

     sin_derivable: LEMMA derivable?(sin);

     deriv_sin    : THEOREM deriv(sin)(x) = cos(x)

     cos_derivable: LEMMA derivable?(cos);

     deriv_cos    : THEOREM deriv(cos)(x) = -sin(x)

     sin2_cos2_derivable: LEMMA derivable?(sin*sin+cos*cos)

     sin2_cos2    : THEOREM sin*sin + cos*cos = const_fun(1)

     sin_cos_one  : THEOREM sin(x)*sin(x) + cos(x)*cos(x) = 1

     sin_lt_1     : LEMMA abs(sin(x)) <= 1

  END trig_props

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 6, column 13) for
      % power_series_deriv[real]
      % generated from assumption power_series_deriv.connected_domain
  IMP_power_series_deriv_TCC1: OBLIGATION connected?[real];

  % Assuming TCC generated (at line 6, column 13) for
      % power_series_deriv[real]
      % generated from assumption power_series_deriv.not_one_element
  IMP_power_series_deriv_TCC2: OBLIGATION not_one_element?[real];

  % Assuming TCC generated (at line 6, column 13) for
      % power_series_deriv[real]
      % generated from assumption power_series_deriv.open
  IMP_power_series_deriv_TCC3: OBLIGATION
    FORALL (x: real): EXISTS (delta: posreal): FORALL (y: real): TRUE;

  % Assuming TCC generated (at line 6, column 13) for
      % power_series_deriv[real]
      % generated from assumption power_series_deriv.ball
  IMP_power_series_deriv_TCC4: OBLIGATION FORALL (x: real): TRUE;

  % Assuming TCC generated (at line 58, column 35) for
      % analysis@derivatives[real]
      % generated from assumption derivatives.deriv_domain
  sin_derivable_TCC1: OBLIGATION deriv_domain?[real];

  % Subtype TCC generated (at line 15, column 32) for  sin
      % expected type  deriv_fun[real]
  deriv_sin_TCC1: OBLIGATION derivable?[real](sin);

  % Subtype TCC generated (at line 19, column 32) for  cos
      % expected type  deriv_fun[real]
  deriv_cos_TCC1: OBLIGATION derivable?[real](cos);


