src/Tools/Metis/src/Normalize.sml
author wenzelm
Mon, 06 Jun 2011 18:05:38 +0200
changeset 42933 7860ffc5ec08
parent 42102 fcfd07f122d4
child 45778 df6e210fb44c
permissions -rw-r--r--
modernized and re-unified Thm.transfer;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
39348
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     1
(* ========================================================================= *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     2
(* NORMALIZING FORMULAS                                                      *)
39502
cffceed8e7fa fix license
blanchet
parents: 39501
diff changeset
     3
(* Copyright (c) 2001 Joe Hurd, distributed under the BSD License            *)
39348
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     4
(* ========================================================================= *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     5
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     6
structure Normalize :> Normalize =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     7
struct
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     8
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     9
open Useful;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    10
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    11
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    12
(* Constants.                                                                *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    13
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    14
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    15
val prefix = "FOFtoCNF";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    16
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    17
val skolemPrefix = "skolem" ^ prefix;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    18
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    19
val definitionPrefix = "definition" ^ prefix;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    20
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    21
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    22
(* Storing huge real numbers as their log.                                   *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    23
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    24
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    25
datatype logReal = LogReal of real;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    26
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    27
fun compareLogReal (LogReal logX, LogReal logY) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    28
    Real.compare (logX,logY);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    29
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    30
val zeroLogReal = LogReal ~1.0;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    31
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    32
val oneLogReal = LogReal 0.0;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    33
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    34
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    35
  fun isZero logX = logX < 0.0;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    36
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    37
  (* Assume logX >= logY >= 0.0 *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    38
  fun add logX logY = logX + Math.ln (1.0 + Math.exp (logY - logX));
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    39
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    40
  fun isZeroLogReal (LogReal logX) = isZero logX;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    41
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    42
  fun multiplyLogReal (LogReal logX) (LogReal logY) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    43
      if isZero logX orelse isZero logY then zeroLogReal
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    44
      else LogReal (logX + logY);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    45
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    46
  fun addLogReal (lx as LogReal logX) (ly as LogReal logY) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    47
      if isZero logX then ly
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    48
      else if isZero logY then lx
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    49
      else if logX < logY then LogReal (add logY logX)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    50
      else LogReal (add logX logY);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    51
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    52
  fun withinRelativeLogReal logDelta (LogReal logX) (LogReal logY) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    53
      isZero logX orelse
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    54
      (not (isZero logY) andalso logX < logY + logDelta);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    55
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    56
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    57
fun toStringLogReal (LogReal logX) = Real.toString logX;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    58
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    59
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    60
(* Counting the clauses that would be generated by conjunctive normal form.  *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    61
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    62
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    63
val countLogDelta = 0.01;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    64
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    65
datatype count = Count of {positive : logReal, negative : logReal};
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    66
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    67
fun countCompare (count1,count2) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    68
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    69
      val Count {positive = p1, negative = _} = count1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    70
      and Count {positive = p2, negative = _} = count2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    71
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    72
      compareLogReal (p1,p2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    73
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    74
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    75
fun countNegate (Count {positive = p, negative = n}) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    76
    Count {positive = n, negative = p};
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    77
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    78
fun countLeqish count1 count2 =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    79
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    80
      val Count {positive = p1, negative = _} = count1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    81
      and Count {positive = p2, negative = _} = count2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    82
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    83
      withinRelativeLogReal countLogDelta p1 p2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    84
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    85
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    86
(*MetisDebug
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    87
fun countEqualish count1 count2 =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    88
    countLeqish count1 count2 andalso
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    89
    countLeqish count2 count1;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    90
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    91
fun countEquivish count1 count2 =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    92
    countEqualish count1 count2 andalso
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    93
    countEqualish (countNegate count1) (countNegate count2);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    94
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    95
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    96
val countTrue = Count {positive = zeroLogReal, negative = oneLogReal};
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    97
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    98
val countFalse = Count {positive = oneLogReal, negative = zeroLogReal};
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    99
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   100
val countLiteral = Count {positive = oneLogReal, negative = oneLogReal};
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   101
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   102
fun countAnd2 (count1,count2) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   103
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   104
      val Count {positive = p1, negative = n1} = count1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   105
      and Count {positive = p2, negative = n2} = count2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   106
      val p = addLogReal p1 p2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   107
      and n = multiplyLogReal n1 n2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   108
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   109
      Count {positive = p, negative = n}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   110
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   111
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   112
fun countOr2 (count1,count2) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   113
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   114
      val Count {positive = p1, negative = n1} = count1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   115
      and Count {positive = p2, negative = n2} = count2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   116
      val p = multiplyLogReal p1 p2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   117
      and n = addLogReal n1 n2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   118
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   119
      Count {positive = p, negative = n}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   120
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   121
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   122
(* Whether countXor2 is associative or not is an open question. *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   123
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   124
fun countXor2 (count1,count2) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   125
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   126
      val Count {positive = p1, negative = n1} = count1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   127
      and Count {positive = p2, negative = n2} = count2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   128
      val p = addLogReal (multiplyLogReal p1 p2) (multiplyLogReal n1 n2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   129
      and n = addLogReal (multiplyLogReal p1 n2) (multiplyLogReal n1 p2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   130
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   131
      Count {positive = p, negative = n}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   132
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   133
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   134
fun countDefinition body_count = countXor2 (countLiteral,body_count);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   135
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   136
val countToString =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   137
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   138
      val rToS = toStringLogReal
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   139
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   140
      fn Count {positive = p, negative = n} =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   141
         "(+" ^ rToS p ^ ",-" ^ rToS n ^ ")"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   142
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   143
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   144
val ppCount = Print.ppMap countToString Print.ppString;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   145
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   146
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   147
(* A type of normalized formula.                                             *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   148
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   149
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   150
datatype formula =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   151
    True
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   152
  | False
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   153
  | Literal of NameSet.set * Literal.literal
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   154
  | And of NameSet.set * count * formula Set.set
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   155
  | Or of NameSet.set * count * formula Set.set
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   156
  | Xor of NameSet.set * count * bool * formula Set.set
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   157
  | Exists of NameSet.set * count * NameSet.set * formula
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   158
  | Forall of NameSet.set * count * NameSet.set * formula;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   159
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   160
fun compare f1_f2 =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   161
    if Portable.pointerEqual f1_f2 then EQUAL
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   162
    else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   163
      case f1_f2 of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   164
        (True,True) => EQUAL
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   165
      | (True,_) => LESS
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   166
      | (_,True) => GREATER
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   167
      | (False,False) => EQUAL
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   168
      | (False,_) => LESS
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   169
      | (_,False) => GREATER
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   170
      | (Literal (_,l1), Literal (_,l2)) => Literal.compare (l1,l2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   171
      | (Literal _, _) => LESS
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   172
      | (_, Literal _) => GREATER
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   173
      | (And (_,_,s1), And (_,_,s2)) => Set.compare (s1,s2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   174
      | (And _, _) => LESS
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   175
      | (_, And _) => GREATER
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   176
      | (Or (_,_,s1), Or (_,_,s2)) => Set.compare (s1,s2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   177
      | (Or _, _) => LESS
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   178
      | (_, Or _) => GREATER
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   179
      | (Xor (_,_,p1,s1), Xor (_,_,p2,s2)) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   180
        (case boolCompare (p1,p2) of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   181
           LESS => LESS
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   182
         | EQUAL => Set.compare (s1,s2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   183
         | GREATER => GREATER)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   184
      | (Xor _, _) => LESS
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   185
      | (_, Xor _) => GREATER
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   186
      | (Exists (_,_,n1,f1), Exists (_,_,n2,f2)) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   187
        (case NameSet.compare (n1,n2) of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   188
           LESS => LESS
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   189
         | EQUAL => compare (f1,f2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   190
         | GREATER => GREATER)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   191
      | (Exists _, _) => LESS
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   192
      | (_, Exists _) => GREATER
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   193
      | (Forall (_,_,n1,f1), Forall (_,_,n2,f2)) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   194
        (case NameSet.compare (n1,n2) of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   195
           LESS => LESS
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   196
         | EQUAL => compare (f1,f2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   197
         | GREATER => GREATER);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   198
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   199
val empty = Set.empty compare;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   200
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   201
val singleton = Set.singleton compare;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   202
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   203
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   204
  fun neg True = False
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   205
    | neg False = True
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   206
    | neg (Literal (fv,lit)) = Literal (fv, Literal.negate lit)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   207
    | neg (And (fv,c,s)) = Or (fv, countNegate c, neg_set s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   208
    | neg (Or (fv,c,s)) = And (fv, countNegate c, neg_set s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   209
    | neg (Xor (fv,c,p,s)) = Xor (fv, c, not p, s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   210
    | neg (Exists (fv,c,n,f)) = Forall (fv, countNegate c, n, neg f)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   211
    | neg (Forall (fv,c,n,f)) = Exists (fv, countNegate c, n, neg f)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   212
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   213
  and neg_set s = Set.foldl neg_elt empty s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   214
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   215
  and neg_elt (f,s) = Set.add s (neg f);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   216
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   217
  val negate = neg;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   218
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   219
  val negateSet = neg_set;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   220
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   221
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   222
fun negateMember x s = Set.member (negate x) s;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   223
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   224
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   225
  fun member s x = negateMember x s;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   226
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   227
  fun negateDisjoint s1 s2 =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   228
      if Set.size s1 < Set.size s2 then not (Set.exists (member s2) s1)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   229
      else not (Set.exists (member s1) s2);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   230
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   231
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   232
fun polarity True = true
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   233
  | polarity False = false
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   234
  | polarity (Literal (_,(pol,_))) = not pol
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   235
  | polarity (And _) = true
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   236
  | polarity (Or _) = false
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   237
  | polarity (Xor (_,_,pol,_)) = pol
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   238
  | polarity (Exists _) = true
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   239
  | polarity (Forall _) = false;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   240
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   241
(*MetisDebug
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   242
val polarity = fn f =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   243
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   244
      val res1 = compare (f, negate f) = LESS
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   245
      val res2 = polarity f
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   246
      val _ = res1 = res2 orelse raise Bug "polarity"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   247
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   248
      res2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   249
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   250
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   251
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   252
fun applyPolarity true fm = fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   253
  | applyPolarity false fm = negate fm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   254
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   255
fun freeVars True = NameSet.empty
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   256
  | freeVars False = NameSet.empty
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   257
  | freeVars (Literal (fv,_)) = fv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   258
  | freeVars (And (fv,_,_)) = fv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   259
  | freeVars (Or (fv,_,_)) = fv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   260
  | freeVars (Xor (fv,_,_,_)) = fv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   261
  | freeVars (Exists (fv,_,_,_)) = fv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   262
  | freeVars (Forall (fv,_,_,_)) = fv;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   263
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   264
fun freeIn v fm = NameSet.member v (freeVars fm);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   265
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   266
val freeVarsSet =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   267
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   268
      fun free (fm,acc) = NameSet.union (freeVars fm) acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   269
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   270
      Set.foldl free NameSet.empty
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   271
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   272
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   273
fun count True = countTrue
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   274
  | count False = countFalse
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   275
  | count (Literal _) = countLiteral
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   276
  | count (And (_,c,_)) = c
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   277
  | count (Or (_,c,_)) = c
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   278
  | count (Xor (_,c,p,_)) = if p then c else countNegate c
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   279
  | count (Exists (_,c,_,_)) = c
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   280
  | count (Forall (_,c,_,_)) = c;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   281
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   282
val countAndSet =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   283
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   284
      fun countAnd (fm,c) = countAnd2 (count fm, c)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   285
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   286
      Set.foldl countAnd countTrue
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   287
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   288
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   289
val countOrSet =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   290
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   291
      fun countOr (fm,c) = countOr2 (count fm, c)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   292
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   293
      Set.foldl countOr countFalse
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   294
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   295
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   296
val countXorSet =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   297
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   298
      fun countXor (fm,c) = countXor2 (count fm, c)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   299
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   300
      Set.foldl countXor countFalse
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   301
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   302
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   303
fun And2 (False,_) = False
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   304
  | And2 (_,False) = False
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   305
  | And2 (True,f2) = f2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   306
  | And2 (f1,True) = f1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   307
  | And2 (f1,f2) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   308
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   309
      val (fv1,c1,s1) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   310
          case f1 of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   311
            And fv_c_s => fv_c_s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   312
          | _ => (freeVars f1, count f1, singleton f1)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   313
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   314
      and (fv2,c2,s2) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   315
          case f2 of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   316
            And fv_c_s => fv_c_s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   317
          | _ => (freeVars f2, count f2, singleton f2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   318
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   319
      if not (negateDisjoint s1 s2) then False
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   320
      else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   321
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   322
          val s = Set.union s1 s2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   323
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   324
          case Set.size s of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   325
            0 => True
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   326
          | 1 => Set.pick s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   327
          | n =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   328
            if n = Set.size s1 + Set.size s2 then
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   329
              And (NameSet.union fv1 fv2, countAnd2 (c1,c2), s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   330
            else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   331
              And (freeVarsSet s, countAndSet s, s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   332
        end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   333
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   334
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   335
val AndList = List.foldl And2 True;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   336
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   337
val AndSet = Set.foldl And2 True;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   338
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   339
fun Or2 (True,_) = True
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   340
  | Or2 (_,True) = True
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   341
  | Or2 (False,f2) = f2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   342
  | Or2 (f1,False) = f1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   343
  | Or2 (f1,f2) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   344
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   345
      val (fv1,c1,s1) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   346
          case f1 of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   347
            Or fv_c_s => fv_c_s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   348
          | _ => (freeVars f1, count f1, singleton f1)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   349
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   350
      and (fv2,c2,s2) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   351
          case f2 of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   352
            Or fv_c_s => fv_c_s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   353
          | _ => (freeVars f2, count f2, singleton f2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   354
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   355
      if not (negateDisjoint s1 s2) then True
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   356
      else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   357
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   358
          val s = Set.union s1 s2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   359
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   360
          case Set.size s of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   361
            0 => False
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   362
          | 1 => Set.pick s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   363
          | n =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   364
            if n = Set.size s1 + Set.size s2 then
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   365
              Or (NameSet.union fv1 fv2, countOr2 (c1,c2), s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   366
            else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   367
              Or (freeVarsSet s, countOrSet s, s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   368
        end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   369
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   370
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   371
val OrList = List.foldl Or2 False;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   372
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   373
val OrSet = Set.foldl Or2 False;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   374
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   375
fun pushOr2 (f1,f2) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   376
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   377
      val s1 = case f1 of And (_,_,s) => s | _ => singleton f1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   378
      and s2 = case f2 of And (_,_,s) => s | _ => singleton f2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   379
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   380
      fun g x1 (x2,acc) = And2 (Or2 (x1,x2), acc)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   381
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   382
      fun f (x1,acc) = Set.foldl (g x1) acc s2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   383
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   384
      Set.foldl f True s1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   385
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   386
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   387
val pushOrList = List.foldl pushOr2 False;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   388
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   389
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   390
  fun normalize fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   391
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   392
        val p = polarity fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   393
        val fm = applyPolarity p fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   394
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   395
        (freeVars fm, count fm, p, singleton fm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   396
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   397
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   398
  fun Xor2 (False,f2) = f2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   399
    | Xor2 (f1,False) = f1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   400
    | Xor2 (True,f2) = negate f2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   401
    | Xor2 (f1,True) = negate f1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   402
    | Xor2 (f1,f2) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   403
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   404
        val (fv1,c1,p1,s1) = case f1 of Xor x => x | _ => normalize f1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   405
        and (fv2,c2,p2,s2) = case f2 of Xor x => x | _ => normalize f2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   406
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   407
        val s = Set.symmetricDifference s1 s2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   408
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   409
        val fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   410
            case Set.size s of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   411
              0 => False
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   412
            | 1 => Set.pick s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   413
            | n =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   414
              if n = Set.size s1 + Set.size s2 then
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   415
                Xor (NameSet.union fv1 fv2, countXor2 (c1,c2), true, s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   416
              else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   417
                Xor (freeVarsSet s, countXorSet s, true, s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   418
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   419
        val p = p1 = p2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   420
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   421
        applyPolarity p fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   422
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   423
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   424
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   425
val XorList = List.foldl Xor2 False;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   426
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   427
val XorSet = Set.foldl Xor2 False;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   428
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   429
fun XorPolarityList (p,l) = applyPolarity p (XorList l);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   430
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   431
fun XorPolaritySet (p,s) = applyPolarity p (XorSet s);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   432
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   433
fun destXor (Xor (_,_,p,s)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   434
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   435
      val (fm1,s) = Set.deletePick s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   436
      val fm2 =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   437
          if Set.size s = 1 then applyPolarity p (Set.pick s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   438
          else Xor (freeVarsSet s, countXorSet s, p, s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   439
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   440
      (fm1,fm2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   441
    end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   442
  | destXor _ = raise Error "destXor";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   443
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   444
fun pushXor fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   445
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   446
      val (f1,f2) = destXor fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   447
      val f1' = negate f1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   448
      and f2' = negate f2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   449
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   450
      And2 (Or2 (f1,f2), Or2 (f1',f2'))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   451
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   452
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   453
fun Exists1 (v,init_fm) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   454
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   455
      fun exists_gen fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   456
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   457
            val fv = NameSet.delete (freeVars fm) v
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   458
            val c = count fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   459
            val n = NameSet.singleton v
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   460
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   461
            Exists (fv,c,n,fm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   462
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   463
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   464
      fun exists fm = if freeIn v fm then exists_free fm else fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   465
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   466
      and exists_free (Or (_,_,s)) = OrList (Set.transform exists s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   467
        | exists_free (fm as And (_,_,s)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   468
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   469
            val sv = Set.filter (freeIn v) s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   470
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   471
            if Set.size sv <> 1 then exists_gen fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   472
            else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   473
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   474
                val fm = Set.pick sv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   475
                val s = Set.delete s fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   476
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   477
                And2 (exists_free fm, AndSet s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   478
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   479
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   480
        | exists_free (Exists (fv,c,n,f)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   481
          Exists (NameSet.delete fv v, c, NameSet.add n v, f)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   482
        | exists_free fm = exists_gen fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   483
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   484
      exists init_fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   485
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   486
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   487
fun ExistsList (vs,f) = List.foldl Exists1 f vs;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   488
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   489
fun ExistsSet (n,f) = NameSet.foldl Exists1 f n;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   490
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   491
fun Forall1 (v,init_fm) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   492
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   493
      fun forall_gen fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   494
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   495
            val fv = NameSet.delete (freeVars fm) v
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   496
            val c = count fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   497
            val n = NameSet.singleton v
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   498
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   499
            Forall (fv,c,n,fm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   500
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   501
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   502
      fun forall fm = if freeIn v fm then forall_free fm else fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   503
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   504
      and forall_free (And (_,_,s)) = AndList (Set.transform forall s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   505
        | forall_free (fm as Or (_,_,s)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   506
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   507
            val sv = Set.filter (freeIn v) s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   508
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   509
            if Set.size sv <> 1 then forall_gen fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   510
            else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   511
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   512
                val fm = Set.pick sv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   513
                val s = Set.delete s fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   514
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   515
                Or2 (forall_free fm, OrSet s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   516
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   517
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   518
        | forall_free (Forall (fv,c,n,f)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   519
          Forall (NameSet.delete fv v, c, NameSet.add n v, f)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   520
        | forall_free fm = forall_gen fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   521
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   522
      forall init_fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   523
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   524
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   525
fun ForallList (vs,f) = List.foldl Forall1 f vs;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   526
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   527
fun ForallSet (n,f) = NameSet.foldl Forall1 f n;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   528
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   529
fun generalize f = ForallSet (freeVars f, f);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   530
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   531
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   532
  fun subst_fv fvSub =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   533
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   534
        fun add_fv (v,s) = NameSet.union (NameMap.get fvSub v) s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   535
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   536
        NameSet.foldl add_fv NameSet.empty
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   537
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   538
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   539
  fun subst_rename (v,(avoid,bv,sub,domain,fvSub)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   540
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   541
        val v' = Term.variantPrime avoid v
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   542
        val avoid = NameSet.add avoid v'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   543
        val bv = NameSet.add bv v'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   544
        val sub = Subst.insert sub (v, Term.Var v')
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   545
        val domain = NameSet.add domain v
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   546
        val fvSub = NameMap.insert fvSub (v, NameSet.singleton v')
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   547
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   548
        (avoid,bv,sub,domain,fvSub)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   549
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   550
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   551
  fun subst_check sub domain fvSub fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   552
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   553
        val domain = NameSet.intersect domain (freeVars fm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   554
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   555
        if NameSet.null domain then fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   556
        else subst_domain sub domain fvSub fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   557
      end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   558
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   559
  and subst_domain sub domain fvSub fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   560
      case fm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   561
        Literal (fv,lit) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   562
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   563
          val fv = NameSet.difference fv domain
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   564
          val fv = NameSet.union fv (subst_fv fvSub domain)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   565
          val lit = Literal.subst sub lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   566
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   567
          Literal (fv,lit)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   568
        end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   569
      | And (_,_,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   570
        AndList (Set.transform (subst_check sub domain fvSub) s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   571
      | Or (_,_,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   572
        OrList (Set.transform (subst_check sub domain fvSub) s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   573
      | Xor (_,_,p,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   574
        XorPolarityList (p, Set.transform (subst_check sub domain fvSub) s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   575
      | Exists fv_c_n_f => subst_quant Exists sub domain fvSub fv_c_n_f
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   576
      | Forall fv_c_n_f => subst_quant Forall sub domain fvSub fv_c_n_f
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   577
      | _ => raise Bug "subst_domain"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   578
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   579
  and subst_quant quant sub domain fvSub (fv,c,bv,fm) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   580
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   581
        val sub_fv = subst_fv fvSub domain
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   582
        val fv = NameSet.union sub_fv (NameSet.difference fv domain)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   583
        val captured = NameSet.intersect bv sub_fv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   584
        val bv = NameSet.difference bv captured
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   585
        val avoid = NameSet.union fv bv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   586
        val (_,bv,sub,domain,fvSub) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   587
            NameSet.foldl subst_rename (avoid,bv,sub,domain,fvSub) captured
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   588
        val fm = subst_domain sub domain fvSub fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   589
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   590
        quant (fv,c,bv,fm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   591
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   592
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   593
  fun subst sub =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   594
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   595
        fun mk_dom (v,tm,(d,fv)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   596
            (NameSet.add d v, NameMap.insert fv (v, Term.freeVars tm))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   597
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   598
        val domain_fvSub = (NameSet.empty, NameMap.new ())
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   599
        val (domain,fvSub) = Subst.foldl mk_dom domain_fvSub sub
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   600
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   601
        subst_check sub domain fvSub
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   602
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   603
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   604
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   605
fun fromFormula fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   606
    case fm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   607
      Formula.True => True
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   608
    | Formula.False => False
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   609
    | Formula.Atom atm => Literal (Atom.freeVars atm, (true,atm))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   610
    | Formula.Not p => negateFromFormula p
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   611
    | Formula.And (p,q) => And2 (fromFormula p, fromFormula q)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   612
    | Formula.Or (p,q) => Or2 (fromFormula p, fromFormula q)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   613
    | Formula.Imp (p,q) => Or2 (negateFromFormula p, fromFormula q)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   614
    | Formula.Iff (p,q) => Xor2 (negateFromFormula p, fromFormula q)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   615
    | Formula.Forall (v,p) => Forall1 (v, fromFormula p)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   616
    | Formula.Exists (v,p) => Exists1 (v, fromFormula p)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   617
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   618
and negateFromFormula fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   619
    case fm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   620
      Formula.True => False
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   621
    | Formula.False => True
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   622
    | Formula.Atom atm => Literal (Atom.freeVars atm, (false,atm))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   623
    | Formula.Not p => fromFormula p
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   624
    | Formula.And (p,q) => Or2 (negateFromFormula p, negateFromFormula q)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   625
    | Formula.Or (p,q) => And2 (negateFromFormula p, negateFromFormula q)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   626
    | Formula.Imp (p,q) => And2 (fromFormula p, negateFromFormula q)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   627
    | Formula.Iff (p,q) => Xor2 (fromFormula p, fromFormula q)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   628
    | Formula.Forall (v,p) => Exists1 (v, negateFromFormula p)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   629
    | Formula.Exists (v,p) => Forall1 (v, negateFromFormula p);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   630
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   631
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   632
  fun lastElt (s : formula Set.set) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   633
      case Set.findr (K true) s of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   634
        NONE => raise Bug "lastElt: empty set"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   635
      | SOME fm => fm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   636
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   637
  fun negateLastElt s =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   638
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   639
        val fm = lastElt s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   640
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   641
        Set.add (Set.delete s fm) (negate fm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   642
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   643
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   644
  fun form fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   645
      case fm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   646
        True => Formula.True
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   647
      | False => Formula.False
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   648
      | Literal (_,lit) => Literal.toFormula lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   649
      | And (_,_,s) => Formula.listMkConj (Set.transform form s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   650
      | Or (_,_,s) => Formula.listMkDisj (Set.transform form s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   651
      | Xor (_,_,p,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   652
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   653
          val s = if p then negateLastElt s else s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   654
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   655
          Formula.listMkEquiv (Set.transform form s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   656
        end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   657
      | Exists (_,_,n,f) => Formula.listMkExists (NameSet.toList n, form f)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   658
      | Forall (_,_,n,f) => Formula.listMkForall (NameSet.toList n, form f);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   659
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   660
  val toFormula = form;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   661
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   662
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   663
fun toLiteral (Literal (_,lit)) = lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   664
  | toLiteral _ = raise Error "Normalize.toLiteral";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   665
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   666
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   667
  fun addLiteral (l,s) = LiteralSet.add s (toLiteral l);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   668
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   669
  fun toClause False = LiteralSet.empty
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   670
    | toClause (Or (_,_,s)) = Set.foldl addLiteral LiteralSet.empty s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   671
    | toClause l = LiteralSet.singleton (toLiteral l);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   672
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   673
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   674
val pp = Print.ppMap toFormula Formula.pp;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   675
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   676
val toString = Print.toString pp;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   677
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   678
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   679
(* Negation normal form.                                                     *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   680
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   681
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   682
fun nnf fm = toFormula (fromFormula fm);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   683
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   684
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   685
(* Basic conjunctive normal form.                                            *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   686
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   687
39501
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   688
local
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   689
  val counter : int StringMap.map ref = ref (StringMap.new ());
39443
e330437cd22a copied the unmodified official Metis 2.3 (15 Sept. 2010) sources into Isabelle
blanchet
parents: 39408
diff changeset
   690
39501
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   691
  fun new n () =
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   692
      let
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   693
        val ref m = counter
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   694
        val s = Name.toString n
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   695
        val i = Option.getOpt (StringMap.peek m s, 0)
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   696
        val () = counter := StringMap.insert m (s, i + 1)
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   697
        val i = if i = 0 then "" else "_" ^ Int.toString i
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   698
        val s = skolemPrefix ^ "_" ^ s ^ i
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   699
      in
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   700
        Name.fromString s
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   701
      end;
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   702
in
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   703
  fun newSkolemFunction n = Portable.critical (new n) ();
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
   704
end;
39348
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   705
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   706
fun skolemize fv bv fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   707
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   708
      val fv = NameSet.transform Term.Var fv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   709
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   710
      fun mk (v,s) = Subst.insert s (v, Term.Fn (newSkolemFunction v, fv))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   711
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   712
      subst (NameSet.foldl mk Subst.empty bv) fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   713
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   714
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   715
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   716
  fun rename avoid fv bv fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   717
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   718
        val captured = NameSet.intersect avoid bv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   719
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   720
        if NameSet.null captured then fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   721
        else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   722
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   723
            fun ren (v,(a,s)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   724
                let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   725
                  val v' = Term.variantPrime a v
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   726
                in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   727
                  (NameSet.add a v', Subst.insert s (v, Term.Var v'))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   728
                end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   729
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   730
            val avoid = NameSet.union (NameSet.union avoid fv) bv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   731
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   732
            val (_,sub) = NameSet.foldl ren (avoid,Subst.empty) captured
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   733
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   734
            subst sub fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   735
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   736
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   737
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   738
  fun cnfFm avoid fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   739
(*MetisTrace5
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   740
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   741
        val fm' = cnfFm' avoid fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   742
        val () = Print.trace pp "Normalize.cnfFm: fm" fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   743
        val () = Print.trace pp "Normalize.cnfFm: fm'" fm'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   744
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   745
        fm'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   746
      end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   747
  and cnfFm' avoid fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   748
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   749
      case fm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   750
        True => True
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   751
      | False => False
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   752
      | Literal _ => fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   753
      | And (_,_,s) => AndList (Set.transform (cnfFm avoid) s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   754
      | Or (fv,_,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   755
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   756
          val avoid = NameSet.union avoid fv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   757
          val (fms,_) = Set.foldl cnfOr ([],avoid) s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   758
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   759
          pushOrList fms
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   760
        end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   761
      | Xor _ => cnfFm avoid (pushXor fm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   762
      | Exists (fv,_,n,f) => cnfFm avoid (skolemize fv n f)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   763
      | Forall (fv,_,n,f) => cnfFm avoid (rename avoid fv n f)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   764
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   765
  and cnfOr (fm,(fms,avoid)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   766
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   767
        val fm = cnfFm avoid fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   768
        val fms = fm :: fms
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   769
        val avoid = NameSet.union avoid (freeVars fm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   770
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   771
        (fms,avoid)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   772
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   773
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   774
  val basicCnf = cnfFm NameSet.empty;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   775
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   776
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   777
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   778
(* Finding the formula definition that minimizes the number of clauses.      *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   779
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   780
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   781
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   782
  type best = count * formula option;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   783
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   784
  fun minBreak countClauses fm best =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   785
      case fm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   786
        True => best
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   787
      | False => best
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   788
      | Literal _ => best
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   789
      | And (_,_,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   790
        minBreakSet countClauses countAnd2 countTrue AndSet s best
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   791
      | Or (_,_,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   792
        minBreakSet countClauses countOr2 countFalse OrSet s best
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   793
      | Xor (_,_,_,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   794
        minBreakSet countClauses countXor2 countFalse XorSet s best
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   795
      | Exists (_,_,_,f) => minBreak countClauses f best
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   796
      | Forall (_,_,_,f) => minBreak countClauses f best
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   797
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   798
  and minBreakSet countClauses count2 count0 mkSet fmSet best =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   799
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   800
        fun cumulatives fms =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   801
            let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   802
              fun fwd (fm,(c1,s1,l)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   803
                  let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   804
                    val c1' = count2 (count fm, c1)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   805
                    and s1' = Set.add s1 fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   806
                  in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   807
                    (c1', s1', (c1,s1,fm) :: l)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   808
                  end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   809
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   810
              fun bwd ((c1,s1,fm),(c2,s2,l)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   811
                  let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   812
                    val c2' = count2 (count fm, c2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   813
                    and s2' = Set.add s2 fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   814
                  in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   815
                    (c2', s2', (c1,s1,fm,c2,s2) :: l)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   816
                  end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   817
39443
e330437cd22a copied the unmodified official Metis 2.3 (15 Sept. 2010) sources into Isabelle
blanchet
parents: 39408
diff changeset
   818
              val (c1,_,fms) = List.foldl fwd (count0,empty,[]) fms
e330437cd22a copied the unmodified official Metis 2.3 (15 Sept. 2010) sources into Isabelle
blanchet
parents: 39408
diff changeset
   819
              val (c2,_,fms) = List.foldl bwd (count0,empty,[]) fms
39348
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   820
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   821
(*MetisDebug
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   822
              val _ = countEquivish c1 c2 orelse
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   823
                      raise Bug ("cumulativeCounts: c1 = " ^ countToString c1 ^
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   824
                                 ", c2 = " ^ countToString c2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   825
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   826
            in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   827
              fms
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   828
            end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   829
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   830
        fun breakSing ((c1,_,fm,c2,_),best) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   831
            let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   832
              val cFms = count2 (c1,c2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   833
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   834
              fun countCls cFm = countClauses (count2 (cFms,cFm))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   835
            in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   836
              minBreak countCls fm best
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   837
            end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   838
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   839
        val breakSet1 =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   840
            let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   841
              fun break c1 s1 fm c2 (best as (bcl,_)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   842
                  if Set.null s1 then best
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   843
                  else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   844
                    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   845
                      val cDef = countDefinition (countXor2 (c1, count fm))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   846
                      val cFm = count2 (countLiteral,c2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   847
                      val cl = countAnd2 (cDef, countClauses cFm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   848
                      val noBetter = countLeqish bcl cl
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   849
                    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   850
                      if noBetter then best
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   851
                      else (cl, SOME (mkSet (Set.add s1 fm)))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   852
                    end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   853
            in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   854
              fn ((c1,s1,fm,c2,s2),best) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   855
                 break c1 s1 fm c2 (break c2 s2 fm c1 best)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   856
            end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   857
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   858
        val fms = Set.toList fmSet
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   859
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   860
        fun breakSet measure best =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   861
            let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   862
              val fms = sortMap (measure o count) countCompare fms
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   863
            in
39443
e330437cd22a copied the unmodified official Metis 2.3 (15 Sept. 2010) sources into Isabelle
blanchet
parents: 39408
diff changeset
   864
              List.foldl breakSet1 best (cumulatives fms)
39348
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   865
            end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   866
39443
e330437cd22a copied the unmodified official Metis 2.3 (15 Sept. 2010) sources into Isabelle
blanchet
parents: 39408
diff changeset
   867
        val best = List.foldl breakSing best (cumulatives fms)
39348
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   868
        val best = breakSet I best
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   869
        val best = breakSet countNegate best
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   870
        val best = breakSet countClauses best
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   871
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   872
        best
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   873
      end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   874
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   875
  fun minimumDefinition fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   876
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   877
        val cl = count fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   878
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   879
        if countLeqish cl countLiteral then NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   880
        else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   881
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   882
            val (cl',def) = minBreak I fm (cl,NONE)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   883
(*MetisTrace1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   884
            val () =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   885
                case def of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   886
                  NONE => ()
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   887
                | SOME d =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   888
                  Print.trace pp ("defCNF: before = " ^ countToString cl ^
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   889
                                  ", after = " ^ countToString cl' ^
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   890
                                  ", definition") d
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   891
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   892
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   893
            def
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   894
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   895
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   896
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   897
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   898
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   899
(* Conjunctive normal form derivations.                                      *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   900
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   901
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   902
datatype thm = Thm of formula * inference
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   903
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   904
and inference =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   905
    Axiom of Formula.formula
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   906
  | Definition of string * Formula.formula
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   907
  | Simplify of thm * thm list
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   908
  | Conjunct of thm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   909
  | Specialize of thm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   910
  | Skolemize of thm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   911
  | Clausify of thm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   912
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   913
fun parentsInference inf =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   914
    case inf of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   915
      Axiom _ => []
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   916
    | Definition _ => []
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   917
    | Simplify (th,ths) => th :: ths
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   918
    | Conjunct th => [th]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   919
    | Specialize th => [th]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   920
    | Skolemize th => [th]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   921
    | Clausify th => [th];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   922
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   923
fun compareThm (Thm (fm1,_), Thm (fm2,_)) = compare (fm1,fm2);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   924
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   925
fun parentsThm (Thm (_,inf)) = parentsInference inf;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   926
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   927
fun mkAxiom fm = Thm (fromFormula fm, Axiom fm);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   928
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   929
fun destThm (Thm (fm,inf)) = (toFormula fm, inf);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   930
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   931
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   932
  val emptyProved : (thm,Formula.formula) Map.map = Map.new compareThm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   933
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   934
  fun isProved proved th = Map.inDomain th proved;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   935
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   936
  fun isUnproved proved th = not (isProved proved th);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   937
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   938
  fun lookupProved proved th =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   939
      case Map.peek proved th of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   940
        SOME fm => fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   941
      | NONE => raise Bug "Normalize.lookupProved";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   942
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   943
  fun prove acc proved ths =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   944
      case ths of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   945
        [] => rev acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   946
      | th :: ths' =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   947
        if isProved proved th then prove acc proved ths'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   948
        else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   949
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   950
            val pars = parentsThm th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   951
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   952
            val deps = List.filter (isUnproved proved) pars
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   953
          in
42102
fcfd07f122d4 new version of Metis 2.3 (29 Dec. 2010)
blanchet
parents: 39502
diff changeset
   954
            if List.null deps then
39348
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   955
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   956
                val (fm,inf) = destThm th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   957
42102
fcfd07f122d4 new version of Metis 2.3 (29 Dec. 2010)
blanchet
parents: 39502
diff changeset
   958
                val fms = List.map (lookupProved proved) pars
39348
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   959
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   960
                val acc = (fm,inf,fms) :: acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   961
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   962
                val proved = Map.insert proved (th,fm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   963
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   964
                prove acc proved ths'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   965
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   966
            else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   967
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   968
                val ths = deps @ ths
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   969
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   970
                prove acc proved ths
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   971
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   972
          end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   973
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   974
  val proveThms = prove [] emptyProved;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   975
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   976
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   977
fun toStringInference inf =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   978
    case inf of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   979
      Axiom _ => "Axiom"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   980
    | Definition _ => "Definition"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   981
    | Simplify _ => "Simplify"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   982
    | Conjunct _ => "Conjunct"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   983
    | Specialize _ => "Specialize"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   984
    | Skolemize _ => "Skolemize"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   985
    | Clausify _ => "Clausify";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   986
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   987
val ppInference = Print.ppMap toStringInference Print.ppString;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   988
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   989
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   990
(* Simplifying with definitions.                                             *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   991
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   992
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   993
datatype simplify =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   994
    Simp of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   995
      {formula : (formula, formula * thm) Map.map,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   996
       andSet : (formula Set.set * formula * thm) list,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   997
       orSet : (formula Set.set * formula * thm) list,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   998
       xorSet : (formula Set.set * formula * thm) list};
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   999
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1000
val simplifyEmpty =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1001
    Simp
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1002
      {formula = Map.new compare,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1003
       andSet = [],
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1004
       orSet = [],
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1005
       xorSet = []};
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1006
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1007
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1008
  fun simpler fm s =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1009
      Set.size s <> 1 orelse
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1010
      case Set.pick s of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1011
        True => false
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1012
      | False => false
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1013
      | Literal _ => false
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1014
      | _ => true;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1015
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1016
  fun addSet set_defs body_def =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1017
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1018
        fun def_body_size (body,_,_) = Set.size body
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1019
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1020
        val body_size = def_body_size body_def
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1021
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1022
        val (body,_,_) = body_def
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1023
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1024
        fun add acc [] = List.revAppend (acc,[body_def])
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1025
          | add acc (l as (bd as (b,_,_)) :: bds) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1026
            case Int.compare (def_body_size bd, body_size) of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1027
              LESS => List.revAppend (acc, body_def :: l)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1028
            | EQUAL =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1029
              if Set.equal b body then List.revAppend (acc,l)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1030
              else add (bd :: acc) bds
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1031
            | GREATER => add (bd :: acc) bds
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1032
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1033
        add [] set_defs
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1034
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1035
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1036
  fun add simp (body,False,th) = add simp (negate body, True, th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1037
    | add simp (True,_,_) = simp
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1038
    | add (Simp {formula,andSet,orSet,xorSet}) (And (_,_,s), def, th) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1039
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1040
        val andSet = addSet andSet (s,def,th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1041
        and orSet = addSet orSet (negateSet s, negate def, th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1042
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1043
        Simp
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1044
          {formula = formula,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1045
           andSet = andSet,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1046
           orSet = orSet,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1047
           xorSet = xorSet}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1048
      end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1049
    | add (Simp {formula,andSet,orSet,xorSet}) (Or (_,_,s), def, th) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1050
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1051
        val orSet = addSet orSet (s,def,th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1052
        and andSet = addSet andSet (negateSet s, negate def, th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1053
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1054
        Simp
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1055
          {formula = formula,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1056
           andSet = andSet,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1057
           orSet = orSet,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1058
           xorSet = xorSet}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1059
      end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1060
    | add simp (Xor (_,_,p,s), def, th) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1061
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1062
        val simp = addXorSet simp (s, applyPolarity p def, th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1063
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1064
        case def of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1065
          True =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1066
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1067
            fun addXorLiteral (fm as Literal _, simp) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1068
                let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1069
                  val s = Set.delete s fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1070
                in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1071
                  if not (simpler fm s) then simp
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1072
                  else addXorSet simp (s, applyPolarity (not p) fm, th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1073
                end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1074
              | addXorLiteral (_,simp) = simp
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1075
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1076
            Set.foldl addXorLiteral simp s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1077
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1078
        | _ => simp
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1079
      end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1080
    | add (simp as Simp {formula,andSet,orSet,xorSet}) (body,def,th) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1081
      if Map.inDomain body formula then simp
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1082
      else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1083
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1084
          val formula = Map.insert formula (body,(def,th))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1085
          val formula = Map.insert formula (negate body, (negate def, th))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1086
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1087
          Simp
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1088
            {formula = formula,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1089
             andSet = andSet,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1090
             orSet = orSet,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1091
             xorSet = xorSet}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1092
        end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1093
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1094
  and addXorSet (simp as Simp {formula,andSet,orSet,xorSet}) (s,def,th) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1095
      if Set.size s = 1 then add simp (Set.pick s, def, th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1096
      else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1097
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1098
          val xorSet = addSet xorSet (s,def,th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1099
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1100
          Simp
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1101
            {formula = formula,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1102
             andSet = andSet,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1103
             orSet = orSet,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1104
             xorSet = xorSet}
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1105
        end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1106
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1107
  fun simplifyAdd simp (th as Thm (fm,_)) = add simp (fm,True,th);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1108
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1109
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1110
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1111
  fun simplifySet set_defs set =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1112
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1113
        fun pred (s,_,_) = Set.subset s set
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1114
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1115
        case List.find pred set_defs of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1116
          NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1117
        | SOME (s,f,th) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1118
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1119
            val set = Set.add (Set.difference set s) f
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1120
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1121
            SOME (set,th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1122
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1123
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1124
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1125
  fun simplify (Simp {formula,andSet,orSet,xorSet}) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1126
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1127
        fun simp fm inf =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1128
            case simp_sub fm inf of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1129
              NONE => simp_top fm inf
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1130
            | SOME (fm,inf) => try_simp_top fm inf
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1131
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1132
        and try_simp_top fm inf =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1133
            case simp_top fm inf of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1134
              NONE => SOME (fm,inf)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1135
            | x => x
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1136
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1137
        and simp_top fm inf =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1138
            case fm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1139
              And (_,_,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1140
              (case simplifySet andSet s of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1141
                 NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1142
               | SOME (s,th) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1143
                 let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1144
                   val fm = AndSet s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1145
                   val inf = th :: inf
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1146
                 in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1147
                   try_simp_top fm inf
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1148
                 end)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1149
            | Or (_,_,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1150
              (case simplifySet orSet s of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1151
                 NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1152
               | SOME (s,th) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1153
                 let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1154
                   val fm = OrSet s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1155
                   val inf = th :: inf
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1156
                 in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1157
                   try_simp_top fm inf
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1158
                 end)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1159
            | Xor (_,_,p,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1160
              (case simplifySet xorSet s of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1161
                 NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1162
               | SOME (s,th) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1163
                 let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1164
                   val fm = XorPolaritySet (p,s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1165
                   val inf = th :: inf
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1166
                 in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1167
                   try_simp_top fm inf
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1168
                 end)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1169
            | _ =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1170
              (case Map.peek formula fm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1171
                 NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1172
               | SOME (fm,th) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1173
                 let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1174
                   val inf = th :: inf
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1175
                 in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1176
                   try_simp_top fm inf
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1177
                 end)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1178
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1179
        and simp_sub fm inf =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1180
            case fm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1181
              And (_,_,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1182
              (case simp_set s inf of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1183
                 NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1184
               | SOME (l,inf) => SOME (AndList l, inf))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1185
            | Or (_,_,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1186
              (case simp_set s inf of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1187
                 NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1188
               | SOME (l,inf) => SOME (OrList l, inf))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1189
            | Xor (_,_,p,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1190
              (case simp_set s inf of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1191
                 NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1192
               | SOME (l,inf) => SOME (XorPolarityList (p,l), inf))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1193
            | Exists (_,_,n,f) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1194
              (case simp f inf of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1195
                 NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1196
               | SOME (f,inf) => SOME (ExistsSet (n,f), inf))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1197
            | Forall (_,_,n,f) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1198
              (case simp f inf of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1199
                 NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1200
               | SOME (f,inf) => SOME (ForallSet (n,f), inf))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1201
            | _ => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1202
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1203
        and simp_set s inf =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1204
            let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1205
              val (changed,l,inf) = Set.foldr simp_set_elt (false,[],inf) s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1206
            in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1207
              if changed then SOME (l,inf) else NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1208
            end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1209
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1210
        and simp_set_elt (fm,(changed,l,inf)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1211
            case simp fm inf of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1212
              NONE => (changed, fm :: l, inf)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1213
            | SOME (fm,inf) => (true, fm :: l, inf)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1214
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1215
        fn th as Thm (fm,_) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1216
           case simp fm [] of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1217
             SOME (fm,ths) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1218
             let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1219
               val inf = Simplify (th,ths)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1220
             in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1221
               Thm (fm,inf)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1222
             end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1223
           | NONE => th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1224
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1225
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1226
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1227
(*MetisTrace2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1228
val simplify = fn simp => fn th as Thm (fm,_) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1229
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1230
      val th' as Thm (fm',_) = simplify simp th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1231
      val () = if compare (fm,fm') = EQUAL then ()
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1232
               else (Print.trace pp "Normalize.simplify: fm" fm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1233
                     Print.trace pp "Normalize.simplify: fm'" fm')
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1234
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1235
      th'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1236
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1237
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1238
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1239
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1240
(* Definitions.                                                              *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1241
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1242
39501
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
  1243
local
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
  1244
  val counter : int ref = ref 0;
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
  1245
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
  1246
  fun new () =
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
  1247
      let
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
  1248
        val ref i = counter
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
  1249
        val () = counter := i + 1
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
  1250
      in
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
  1251
        definitionPrefix ^ "_" ^ Int.toString i
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
  1252
      end;
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
  1253
in
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
  1254
  fun newDefinitionRelation () = Portable.critical new ();
aaa7078fff55 updated source files with Metis 2.3 (timestamp: 16 Sept. 2010)
blanchet
parents: 39445
diff changeset
  1255
end;
39348
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1256
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1257
fun newDefinition def =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1258
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1259
      val fv = freeVars def
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1260
      val rel = newDefinitionRelation ()
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1261
      val atm = (Name.fromString rel, NameSet.transform Term.Var fv)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1262
      val fm = Formula.Iff (Formula.Atom atm, toFormula def)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1263
      val fm = Formula.setMkForall (fv,fm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1264
      val inf = Definition (rel,fm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1265
      val lit = Literal (fv,(false,atm))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1266
      val fm = Xor2 (lit,def)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1267
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1268
      Thm (fm,inf)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1269
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1270
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1271
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1272
(* Definitional conjunctive normal form.                                     *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1273
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1274
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1275
datatype cnf =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1276
    ConsistentCnf of simplify
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1277
  | InconsistentCnf;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1278
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1279
val initialCnf = ConsistentCnf simplifyEmpty;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1280
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1281
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1282
  fun def_cnf_inconsistent th =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1283
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1284
        val cls = [(LiteralSet.empty,th)]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1285
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1286
        (cls,InconsistentCnf)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1287
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1288
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1289
  fun def_cnf_clause inf (fm,acc) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1290
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1291
        val cl = toClause fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1292
        val th = Thm (fm,inf)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1293
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1294
        (cl,th) :: acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1295
      end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1296
(*MetisDebug
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1297
      handle Error err =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1298
        (Print.trace pp "Normalize.addCnf.def_cnf_clause: fm" fm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1299
         raise Bug ("Normalize.addCnf.def_cnf_clause: " ^ err));
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1300
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1301
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1302
  fun def_cnf cls simp ths =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1303
      case ths of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1304
        [] => (cls, ConsistentCnf simp)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1305
      | th :: ths => def_cnf_formula cls simp (simplify simp th) ths
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1306
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1307
  and def_cnf_formula cls simp (th as Thm (fm,_)) ths =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1308
      case fm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1309
        True => def_cnf cls simp ths
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1310
      | False => def_cnf_inconsistent th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1311
      | And (_,_,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1312
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1313
          fun add (f,z) = Thm (f, Conjunct th) :: z
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1314
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1315
          def_cnf cls simp (Set.foldr add ths s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1316
        end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1317
      | Exists (fv,_,n,f) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1318
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1319
          val th = Thm (skolemize fv n f, Skolemize th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1320
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1321
          def_cnf_formula cls simp th ths
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1322
        end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1323
      | Forall (_,_,_,f) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1324
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1325
          val th = Thm (f, Specialize th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1326
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1327
          def_cnf_formula cls simp th ths
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1328
        end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1329
      | _ =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1330
        case minimumDefinition fm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1331
          SOME def =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1332
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1333
            val ths = th :: ths
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1334
            val th = newDefinition def
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1335
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1336
            def_cnf_formula cls simp th ths
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1337
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1338
        | NONE =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1339
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1340
            val simp = simplifyAdd simp th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1341
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1342
            val fm = basicCnf fm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1343
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1344
            val inf = Clausify th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1345
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1346
            case fm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1347
              True => def_cnf cls simp ths
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1348
            | False => def_cnf_inconsistent (Thm (fm,inf))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1349
            | And (_,_,s) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1350
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1351
                val inf = Conjunct (Thm (fm,inf))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1352
                val cls = Set.foldl (def_cnf_clause inf) cls s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1353
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1354
                def_cnf cls simp ths
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1355
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1356
            | fm => def_cnf (def_cnf_clause inf (fm,cls)) simp ths
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1357
          end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1358
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1359
  fun addCnf th cnf =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1360
      case cnf of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1361
        ConsistentCnf simp => def_cnf [] simp [th]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1362
      | InconsistentCnf => ([],cnf);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1363
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1364
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1365
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1366
  fun add (th,(cls,cnf)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1367
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1368
        val (cls',cnf) = addCnf th cnf
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1369
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1370
        (cls' @ cls, cnf)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1371
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1372
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1373
  fun proveCnf ths =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1374
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1375
        val (cls,_) = List.foldl add ([],initialCnf) ths
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1376
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1377
        rev cls
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1378
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1379
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1380
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1381
fun cnf fm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1382
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1383
      val cls = proveCnf [mkAxiom fm]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1384
    in
42102
fcfd07f122d4 new version of Metis 2.3 (29 Dec. 2010)
blanchet
parents: 39502
diff changeset
  1385
      List.map fst cls
39348
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1386
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1387
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
  1388
end