src/HOL/NatArith.ML
author paulson
Sat, 09 Jun 2001 08:44:04 +0200
changeset 11367 7b2dbfb5cc3d
parent 10962 cda180b1e2e0
child 11385 bad599516730
permissions -rw-r--r--
addition of the GREATEST quantifier
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10214
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
     1
(*  Title:      HOL/NatArith.ML
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
     2
    ID:         $Id$
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
     3
    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
     4
    Copyright   1998  University of Cambridge
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
     5
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
     6
Further proofs about elementary arithmetic, using the arithmetic proof
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
     7
procedures.
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
     8
*)
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
     9
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    10
(*legacy ...*)
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    11
structure NatArith = struct val thy = the_context () end;
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    12
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    13
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    14
Goal "m <= m*(m::nat)";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    15
by (induct_tac "m" 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    16
by Auto_tac;
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    17
qed "le_square";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    18
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    19
Goal "(m::nat) <= m*(m*m)";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    20
by (induct_tac "m" 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    21
by Auto_tac;
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    22
qed "le_cube";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    23
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    24
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    25
(*** Subtraction laws -- mostly from Clemens Ballarin ***)
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    26
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    27
Goal "[| a < (b::nat); c <= a |] ==> a-c < b-c";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    28
by (arith_tac 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    29
qed "diff_less_mono";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    30
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    31
Goal "(i < j-k) = (i+k < (j::nat))";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    32
by (arith_tac 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    33
qed "less_diff_conv";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    34
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    35
Goal "(j-k <= (i::nat)) = (j <= i+k)";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    36
by (arith_tac 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    37
qed "le_diff_conv";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    38
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    39
Goal "k <= j ==> (i <= j-k) = (i+k <= (j::nat))";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    40
by (arith_tac 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    41
qed "le_diff_conv2";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    42
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    43
Goal "i <= (n::nat) ==> n - (n - i) = i";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    44
by (arith_tac 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    45
qed "diff_diff_cancel";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    46
Addsimps [diff_diff_cancel];
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    47
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    48
Goal "k <= (n::nat) ==> m <= n + m - k";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    49
by (arith_tac 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    50
qed "le_add_diff";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    51
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    52
(*Replaces the previous diff_less and le_diff_less, which had the stronger
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    53
  second premise n<=m*)
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    54
Goal "!!m::nat. [| 0<n; 0<m |] ==> m - n < m";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    55
by (arith_tac 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    56
qed "diff_less";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    57
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    58
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    59
(** Simplification of relational expressions involving subtraction **)
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    60
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    61
Goal "[| k <= m;  k <= (n::nat) |] ==> ((m-k) - (n-k)) = (m-n)";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    62
by (asm_simp_tac (simpset() addsplits [nat_diff_split]) 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    63
qed "diff_diff_eq";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    64
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    65
Goal "[| k <= m;  k <= (n::nat) |] ==> (m-k = n-k) = (m=n)";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    66
by (auto_tac (claset(), simpset() addsplits [nat_diff_split]));
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    67
qed "eq_diff_iff";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    68
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    69
Goal "[| k <= m;  k <= (n::nat) |] ==> (m-k < n-k) = (m<n)";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    70
by (auto_tac (claset(), simpset() addsplits [nat_diff_split]));
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    71
qed "less_diff_iff";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    72
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    73
Goal "[| k <= m;  k <= (n::nat) |] ==> (m-k <= n-k) = (m<=n)";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    74
by (auto_tac (claset(), simpset() addsplits [nat_diff_split]));
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    75
qed "le_diff_iff";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    76
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    77
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    78
(** (Anti)Monotonicity of subtraction -- by Stephan Merz **)
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    79
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    80
(* Monotonicity of subtraction in first argument *)
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    81
Goal "m <= (n::nat) ==> (m-l) <= (n-l)";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    82
by (asm_simp_tac (simpset() addsplits [nat_diff_split]) 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    83
qed "diff_le_mono";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    84
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    85
Goal "m <= (n::nat) ==> (l-n) <= (l-m)";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    86
by (asm_simp_tac (simpset() addsplits [nat_diff_split]) 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    87
qed "diff_le_mono2";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    88
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    89
Goal "[| m < (n::nat); m<l |] ==> (l-n) < (l-m)";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    90
by (asm_simp_tac (simpset() addsplits [nat_diff_split]) 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    91
qed "diff_less_mono2";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    92
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    93
Goal "!!m::nat. [| m-n = 0; n-m = 0 |] ==>  m=n";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    94
by (asm_full_simp_tac (simpset() addsplits [nat_diff_split]) 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    95
qed "diffs0_imp_equal";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    96
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    97
(** Lemmas for ex/Factorization **)
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    98
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
    99
Goal "!!m::nat. [| 1<n; 1<m |] ==> 1<m*n";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   100
by (case_tac "m" 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   101
by Auto_tac;
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   102
qed "one_less_mult"; 
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   103
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   104
Goal "!!m::nat. [| 1<n; 1<m |] ==> n<m*n";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   105
by (case_tac "m" 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   106
by Auto_tac;
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   107
qed "n_less_m_mult_n"; 
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   108
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   109
Goal "!!m::nat. [| 1<n; 1<m |] ==> n<n*m";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   110
by (case_tac "m" 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   111
by Auto_tac;
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   112
qed "n_less_n_mult_m"; 
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   113
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   114
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   115
(** Rewriting to pull differences out **)
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   116
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   117
Goal "k<=j --> i - (j - k) = i + (k::nat) - j";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   118
by (arith_tac 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   119
qed "diff_diff_right";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   120
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   121
Goal "k <= j ==> m - Suc (j - k) = m + k - Suc j";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   122
by (arith_tac 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   123
qed "diff_Suc_diff_eq1"; 
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   124
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   125
Goal "k <= j ==> Suc (j - k) - m = Suc j - (k + m)";
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   126
by (arith_tac 1);
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   127
qed "diff_Suc_diff_eq2"; 
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   128
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   129
(*The others are
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   130
      i - j - k = i - (j + k),
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   131
      k <= j ==> j - k + i = j + i - k,
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   132
      k <= j ==> i + (j - k) = i + j - k *)
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   133
Addsimps [diff_diff_left, diff_diff_right, diff_add_assoc2 RS sym, 
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   134
	  diff_add_assoc RS sym, diff_Suc_diff_eq1, diff_Suc_diff_eq2];
77349ed89f45 *** empty log message ***
nipkow
parents:
diff changeset
   135
11367
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   136
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   137
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   138
(** GREATEST theorems for type "nat": not dual to LEAST, since there is
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   139
    no greatest natural number.  [The LEAST proofs are in Nat.ML, but the
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   140
    GREATEST proofs require more infrastructure.] **)
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   141
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   142
Goal "[|P k;  ALL x. P x --> (EX y. P y & ~ ((m y::nat) <= m x))|] \
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   143
\     ==> EX y. P y & ~ (m y < m k + n)";
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   144
by (induct_tac "n" 1);
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   145
by (Force_tac 1); 
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   146
(*ind step*)
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   147
by (force_tac (claset(), simpset() addsimps [le_Suc_eq]) 1); 
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   148
qed "ex_has_greatest_nat_lemma";
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   149
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   150
Goal "[|P k;  ! y. P y --> m y < b|] \
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   151
\     ==> ? x. P x & (! y. P y --> (m y::nat) <= m x)";
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   152
by (rtac ccontr 1); 
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   153
by (cut_inst_tac [("P","P"),("n","b - m k")] ex_has_greatest_nat_lemma 1);
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   154
by (subgoal_tac "m k <= b" 3);
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   155
by Auto_tac;  
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   156
qed "ex_has_greatest_nat";
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   157
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   158
Goalw [GreatestM_def]
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   159
     "[|P k;  ! y. P y --> m y < b|] \
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   160
\     ==> P (GreatestM m P) & (!y. P y --> (m y::nat) <= m (GreatestM m P))";
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   161
by (rtac someI_ex 1);
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   162
by (etac ex_has_greatest_nat 1);
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   163
by (assume_tac 1); 
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   164
qed "GreatestM_nat_lemma";
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   165
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   166
bind_thm ("GreatestM_natI", GreatestM_nat_lemma RS conjunct1);
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   167
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   168
Goal "[|P x;  ! y. P y --> m y < b|] \
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   169
\     ==> (m x::nat) <= m (GreatestM m P)";
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   170
by (blast_tac (claset() addDs [GreatestM_nat_lemma RS conjunct2 RS spec]) 1);
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   171
qed "GreatestM_nat_le";
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   172
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   173
(** Specialization to GREATEST **)
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   174
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   175
Goalw [Greatest_def]
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   176
     "[|P (k::nat);  ! y. P y --> y < b|] ==> P (GREATEST x. P x)";
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   177
by (rtac GreatestM_natI 1); 
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   178
by Auto_tac;  
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   179
qed "GreatestI";
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   180
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   181
Goalw [Greatest_def]
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   182
     "[|P x;  ! y. P y --> y < b|] ==> (x::nat) <= (GREATEST x. P x)";
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   183
by (rtac GreatestM_nat_le 1); 
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   184
by Auto_tac;  
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   185
qed "GreatestM_nat_le";
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   186
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   187
(*No analogue of not_less_Least or Least_Suc yet, since it isn't used much*)
7b2dbfb5cc3d addition of the GREATEST quantifier
paulson
parents: 10962
diff changeset
   188