src/Tools/Metis/src/Rule.sml
author blanchet
Mon, 13 Sep 2010 21:09:43 +0200
changeset 39348 6f9c9899f99f
child 39349 2d0a4361c3ef
permissions -rw-r--r--
new version of the Metis files
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
(* DERIVED RULES FOR CREATING FIRST ORDER LOGIC THEOREMS                     *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
     3
(* Copyright (c) 2001-2006 Joe Hurd, distributed under the GNU GPL version 2 *)
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 Rule :> Rule =
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
(* Variable names.                                                           *)
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 xVarName = Name.fromString "x";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    16
val xVar = Term.Var xVarName;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    17
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    18
val yVarName = Name.fromString "y";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    19
val yVar = Term.Var yVarName;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    20
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    21
val zVarName = Name.fromString "z";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    22
val zVar = Term.Var zVarName;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    23
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    24
fun xIVarName i = Name.fromString ("x" ^ Int.toString i);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    25
fun xIVar i = Term.Var (xIVarName i);
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 yIVarName i = Name.fromString ("y" ^ Int.toString i);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    28
fun yIVar i = Term.Var (yIVarName i);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    29
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    30
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    31
(*                                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    32
(* --------- reflexivity                                                     *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    33
(*   x = x                                                                   *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    34
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    35
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    36
fun reflexivityRule x = Thm.refl x;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    37
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    38
val reflexivity = reflexivityRule xVar;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    39
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    40
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    41
(*                                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    42
(* --------------------- symmetry                                            *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    43
(*   ~(x = y) \/ y = x                                                       *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    44
(* ------------------------------------------------------------------------- *)
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 symmetryRule x y =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    47
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    48
      val reflTh = reflexivityRule x
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    49
      val reflLit = Thm.destUnit reflTh
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    50
      val eqTh = Thm.equality reflLit [0] y
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    51
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    52
      Thm.resolve reflLit reflTh eqTh
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    53
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    54
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    55
val symmetry = symmetryRule xVar yVar;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    56
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    57
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    58
(*                                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    59
(* --------------------------------- transitivity                            *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    60
(*   ~(x = y) \/ ~(y = z) \/ x = z                                           *)
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 transitivity =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    64
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    65
      val eqTh = Thm.equality (Literal.mkEq (yVar,zVar)) [0] xVar
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    66
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    67
      Thm.resolve (Literal.mkEq (yVar,xVar)) symmetry eqTh
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    68
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    69
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    70
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    71
(*   x = y \/ C                                                              *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    72
(* -------------- symEq (x = y)                                              *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    73
(*   y = x \/ C                                                              *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    74
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    75
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    76
fun symEq lit th =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    77
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    78
      val (x,y) = Literal.destEq lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    79
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    80
      if Term.equal x y then th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    81
      else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    82
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    83
          val sub = Subst.fromList [(xVarName,x),(yVarName,y)]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    84
          val symTh = Thm.subst sub symmetry
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    85
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    86
          Thm.resolve lit th symTh
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    87
        end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    88
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    89
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    90
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    91
(* An equation consists of two terms (t,u) plus a theorem (stronger than)    *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    92
(* t = u \/ C.                                                               *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    93
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    94
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    95
type equation = (Term.term * Term.term) * Thm.thm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    96
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    97
fun ppEquation (_,th) = Thm.pp th;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    98
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    99
val equationToString = Print.toString ppEquation;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   100
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   101
fun equationLiteral (t_u,th) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   102
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   103
      val lit = Literal.mkEq t_u
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   104
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   105
      if LiteralSet.member lit (Thm.clause th) then SOME lit else NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   106
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   107
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   108
fun reflEqn t = ((t,t), Thm.refl t);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   109
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   110
fun symEqn (eqn as ((t,u), th)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   111
    if Term.equal t u then eqn
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   112
    else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   113
      ((u,t),
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   114
       case equationLiteral eqn of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   115
         SOME t_u => symEq t_u th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   116
       | NONE => th);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   117
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   118
fun transEqn (eqn1 as ((x,y), th1)) (eqn2 as ((_,z), th2)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   119
    if Term.equal x y then eqn2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   120
    else if Term.equal y z then eqn1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   121
    else if Term.equal x z then reflEqn x
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   122
    else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   123
      ((x,z),
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   124
       case equationLiteral eqn1 of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   125
         NONE => th1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   126
       | SOME x_y =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   127
         case equationLiteral eqn2 of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   128
           NONE => th2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   129
         | SOME y_z =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   130
           let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   131
             val sub = Subst.fromList [(xVarName,x),(yVarName,y),(zVarName,z)]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   132
             val th = Thm.subst sub transitivity
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   133
             val th = Thm.resolve x_y th1 th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   134
             val th = Thm.resolve y_z th2 th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   135
           in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   136
             th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   137
           end);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   138
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   139
(*MetisDebug
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   140
val transEqn = fn eqn1 => fn eqn2 =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   141
    transEqn eqn1 eqn2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   142
    handle Error err =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   143
      raise Error ("Rule.transEqn:\neqn1 = " ^ equationToString eqn1 ^
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   144
                   "\neqn2 = " ^ equationToString eqn2 ^ "\n" ^ err);
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
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   148
(* A conversion takes a term t and either:                                   *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   149
(* 1. Returns a term u together with a theorem (stronger than) t = u \/ C.   *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   150
(* 2. Raises an Error exception.                                             *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   151
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   152
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   153
type conv = Term.term -> Term.term * Thm.thm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   154
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   155
fun allConv tm = (tm, Thm.refl tm);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   156
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   157
val noConv : conv = fn _ => raise Error "noConv";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   158
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   159
fun traceConv s conv tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   160
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   161
      val res as (tm',th) = conv tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   162
      val () = print (s ^ ": " ^ Term.toString tm ^ " --> " ^
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   163
                      Term.toString tm' ^ " " ^ Thm.toString th ^ "\n")
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   164
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   165
      res
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   166
    end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   167
    handle Error err =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   168
      (print (s ^ ": " ^ Term.toString tm ^ " --> Error: " ^ err ^ "\n");
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   169
       raise Error (s ^ ": " ^ err));
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   170
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   171
fun thenConvTrans tm (tm',th1) (tm'',th2) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   172
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   173
      val eqn1 = ((tm,tm'),th1)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   174
      and eqn2 = ((tm',tm''),th2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   175
      val (_,th) = transEqn eqn1 eqn2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   176
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   177
      (tm'',th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   178
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   179
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   180
fun thenConv conv1 conv2 tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   181
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   182
      val res1 as (tm',_) = conv1 tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   183
      val res2 = conv2 tm'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   184
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   185
      thenConvTrans tm res1 res2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   186
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   187
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   188
fun orelseConv (conv1 : conv) conv2 tm = conv1 tm handle Error _ => conv2 tm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   189
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   190
fun tryConv conv = orelseConv conv allConv;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   191
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   192
fun changedConv conv tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   193
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   194
      val res as (tm',_) = conv tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   195
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   196
      if tm = tm' then raise Error "changedConv" else res
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   197
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   198
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   199
fun repeatConv conv tm = tryConv (thenConv conv (repeatConv conv)) tm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   200
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   201
fun firstConv [] _ = raise Error "firstConv"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   202
  | firstConv [conv] tm = conv tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   203
  | firstConv (conv :: convs) tm = orelseConv conv (firstConv convs) tm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   204
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   205
fun everyConv [] tm = allConv tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   206
  | everyConv [conv] tm = conv tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   207
  | everyConv (conv :: convs) tm = thenConv conv (everyConv convs) tm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   208
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   209
fun rewrConv (eqn as ((x,y), eqTh)) path tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   210
    if Term.equal x y then allConv tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   211
    else if null path then (y,eqTh)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   212
    else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   213
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   214
        val reflTh = Thm.refl tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   215
        val reflLit = Thm.destUnit reflTh
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   216
        val th = Thm.equality reflLit (1 :: path) y
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   217
        val th = Thm.resolve reflLit reflTh th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   218
        val th =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   219
            case equationLiteral eqn of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   220
              NONE => th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   221
            | SOME x_y => Thm.resolve x_y eqTh th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   222
        val tm' = Term.replace tm (path,y)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   223
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   224
        (tm',th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   225
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   226
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   227
(*MetisDebug
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   228
val rewrConv = fn eqn as ((x,y),eqTh) => fn path => fn tm =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   229
    rewrConv eqn path tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   230
    handle Error err =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   231
      raise Error ("Rule.rewrConv:\nx = " ^ Term.toString x ^
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   232
                   "\ny = " ^ Term.toString y ^
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   233
                   "\neqTh = " ^ Thm.toString eqTh ^
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   234
                   "\npath = " ^ Term.pathToString path ^
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   235
                   "\ntm = " ^ Term.toString tm ^ "\n" ^ err);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   236
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   237
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   238
fun pathConv conv path tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   239
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   240
      val x = Term.subterm tm path
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   241
      val (y,th) = conv x
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   242
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   243
      rewrConv ((x,y),th) path tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   244
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   245
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   246
fun subtermConv conv i = pathConv conv [i];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   247
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   248
fun subtermsConv _ (tm as Term.Var _) = allConv tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   249
  | subtermsConv conv (tm as Term.Fn (_,a)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   250
    everyConv (map (subtermConv conv) (interval 0 (length a))) tm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   251
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   252
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   253
(* Applying a conversion to every subterm, with some traversal strategy.     *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   254
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   255
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   256
fun bottomUpConv conv tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   257
    thenConv (subtermsConv (bottomUpConv conv)) (repeatConv conv) tm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   258
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   259
fun topDownConv conv tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   260
    thenConv (repeatConv conv) (subtermsConv (topDownConv conv)) tm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   261
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   262
fun repeatTopDownConv conv =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   263
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   264
      fun f tm = thenConv (repeatConv conv) g tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   265
      and g tm = thenConv (subtermsConv f) h tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   266
      and h tm = tryConv (thenConv conv f) tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   267
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   268
      f
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   269
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   270
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   271
(*MetisDebug
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   272
val repeatTopDownConv = fn conv => fn tm =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   273
    repeatTopDownConv conv tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   274
    handle Error err => raise Error ("repeatTopDownConv: " ^ err);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   275
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   276
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   277
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   278
(* A literule (bad pun) takes a literal L and either:                        *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   279
(* 1. Returns a literal L' with a theorem (stronger than) ~L \/ L' \/ C.     *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   280
(* 2. Raises an Error exception.                                             *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   281
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   282
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   283
type literule = Literal.literal -> Literal.literal * Thm.thm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   284
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   285
fun allLiterule lit = (lit, Thm.assume lit);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   286
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   287
val noLiterule : literule = fn _ => raise Error "noLiterule";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   288
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   289
fun thenLiterule literule1 literule2 lit =
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
      val res1 as (lit',th1) = literule1 lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   292
      val res2 as (lit'',th2) = literule2 lit'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   293
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   294
      if Literal.equal lit lit' then res2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   295
      else if Literal.equal lit' lit'' then res1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   296
      else if Literal.equal lit lit'' then allLiterule lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   297
      else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   298
        (lit'',
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   299
         if not (Thm.member lit' th1) then th1
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   300
         else if not (Thm.negateMember lit' th2) then th2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   301
         else Thm.resolve lit' th1 th2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   302
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   303
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   304
fun orelseLiterule (literule1 : literule) literule2 lit =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   305
    literule1 lit handle Error _ => literule2 lit;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   306
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   307
fun tryLiterule literule = orelseLiterule literule allLiterule;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   308
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   309
fun changedLiterule literule lit =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   310
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   311
      val res as (lit',_) = literule lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   312
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   313
      if lit = lit' then raise Error "changedLiterule" else res
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   314
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   315
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   316
fun repeatLiterule literule lit =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   317
    tryLiterule (thenLiterule literule (repeatLiterule literule)) lit;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   318
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   319
fun firstLiterule [] _ = raise Error "firstLiterule"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   320
  | firstLiterule [literule] lit = literule lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   321
  | firstLiterule (literule :: literules) lit =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   322
    orelseLiterule literule (firstLiterule literules) lit;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   323
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   324
fun everyLiterule [] lit = allLiterule lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   325
  | everyLiterule [literule] lit = literule lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   326
  | everyLiterule (literule :: literules) lit =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   327
    thenLiterule literule (everyLiterule literules) lit;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   328
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   329
fun rewrLiterule (eqn as ((x,y),eqTh)) path lit =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   330
    if Term.equal x y then allLiterule lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   331
    else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   332
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   333
        val th = Thm.equality lit path y
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   334
        val th =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   335
            case equationLiteral eqn of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   336
              NONE => th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   337
            | SOME x_y => Thm.resolve x_y eqTh th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   338
        val lit' = Literal.replace lit (path,y)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   339
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   340
        (lit',th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   341
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   342
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   343
(*MetisDebug
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   344
val rewrLiterule = fn eqn => fn path => fn lit =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   345
    rewrLiterule eqn path lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   346
    handle Error err =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   347
      raise Error ("Rule.rewrLiterule:\neqn = " ^ equationToString eqn ^
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   348
                   "\npath = " ^ Term.pathToString path ^
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   349
                   "\nlit = " ^ Literal.toString lit ^ "\n" ^ err);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   350
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   351
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   352
fun pathLiterule conv path lit =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   353
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   354
      val tm = Literal.subterm lit path
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   355
      val (tm',th) = conv tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   356
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   357
      rewrLiterule ((tm,tm'),th) path lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   358
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   359
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   360
fun argumentLiterule conv i = pathLiterule conv [i];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   361
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   362
fun allArgumentsLiterule conv lit =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   363
    everyLiterule
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   364
      (map (argumentLiterule conv) (interval 0 (Literal.arity lit))) lit;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   365
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   366
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   367
(* A rule takes one theorem and either deduces another or raises an Error    *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   368
(* exception.                                                                *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   369
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   370
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   371
type rule = Thm.thm -> Thm.thm;
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 allRule : rule = fn th => th;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   374
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   375
val noRule : rule = fn _ => raise Error "noRule";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   376
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   377
fun thenRule (rule1 : rule) (rule2 : rule) th = rule1 (rule2 th);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   378
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   379
fun orelseRule (rule1 : rule) rule2 th = rule1 th handle Error _ => rule2 th;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   380
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   381
fun tryRule rule = orelseRule rule allRule;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   382
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   383
fun changedRule rule th =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   384
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   385
      val th' = rule th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   386
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   387
      if not (LiteralSet.equal (Thm.clause th) (Thm.clause th')) then th'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   388
      else raise Error "changedRule"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   389
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   390
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   391
fun repeatRule rule lit = tryRule (thenRule rule (repeatRule rule)) lit;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   392
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   393
fun firstRule [] _ = raise Error "firstRule"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   394
  | firstRule [rule] th = rule th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   395
  | firstRule (rule :: rules) th = orelseRule rule (firstRule rules) th;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   396
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   397
fun everyRule [] th = allRule th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   398
  | everyRule [rule] th = rule th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   399
  | everyRule (rule :: rules) th = thenRule rule (everyRule rules) th;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   400
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   401
fun literalRule literule lit th =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   402
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   403
      val (lit',litTh) = literule lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   404
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   405
      if Literal.equal lit lit' then th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   406
      else if not (Thm.negateMember lit litTh) then litTh
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   407
      else Thm.resolve lit th litTh
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   408
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   409
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   410
(*MetisDebug
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   411
val literalRule = fn literule => fn lit => fn th =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   412
    literalRule literule lit th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   413
    handle Error err =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   414
      raise Error ("Rule.literalRule:\nlit = " ^ Literal.toString lit ^
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   415
                   "\nth = " ^ Thm.toString th ^ "\n" ^ err);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   416
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   417
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   418
fun rewrRule eqTh lit path = literalRule (rewrLiterule eqTh path) lit;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   419
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   420
fun pathRule conv lit path = literalRule (pathLiterule conv path) lit;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   421
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   422
fun literalsRule literule =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   423
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   424
      fun f (lit,th) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   425
          if Thm.member lit th then literalRule literule lit th else th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   426
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   427
      fn lits => fn th => LiteralSet.foldl f th lits
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   428
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   429
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   430
fun allLiteralsRule literule th = literalsRule literule (Thm.clause th) th;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   431
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   432
fun convRule conv = allLiteralsRule (allArgumentsLiterule conv);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   433
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   434
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   435
(*                                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   436
(* ---------------------------------------------- functionCongruence (f,n)   *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   437
(*   ~(x0 = y0) \/ ... \/ ~(x{n-1} = y{n-1}) \/                              *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   438
(*   f x0 ... x{n-1} = f y0 ... y{n-1}                                       *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   439
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   440
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   441
fun functionCongruence (f,n) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   442
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   443
      val xs = List.tabulate (n,xIVar)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   444
      and ys = List.tabulate (n,yIVar)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   445
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   446
      fun cong ((i,yi),(th,lit)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   447
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   448
            val path = [1,i]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   449
            val th = Thm.resolve lit th (Thm.equality lit path yi)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   450
            val lit = Literal.replace lit (path,yi)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   451
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   452
            (th,lit)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   453
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   454
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   455
      val reflTh = Thm.refl (Term.Fn (f,xs))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   456
      val reflLit = Thm.destUnit reflTh
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   457
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   458
      fst (foldl cong (reflTh,reflLit) (enumerate ys))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   459
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   460
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   461
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   462
(*                                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   463
(* ---------------------------------------------- relationCongruence (R,n)   *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   464
(*   ~(x0 = y0) \/ ... \/ ~(x{n-1} = y{n-1}) \/                              *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   465
(*   ~R x0 ... x{n-1} \/ R y0 ... y{n-1}                                     *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   466
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   467
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   468
fun relationCongruence (R,n) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   469
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   470
      val xs = List.tabulate (n,xIVar)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   471
      and ys = List.tabulate (n,yIVar)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   472
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   473
      fun cong ((i,yi),(th,lit)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   474
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   475
            val path = [i]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   476
            val th = Thm.resolve lit th (Thm.equality lit path yi)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   477
            val lit = Literal.replace lit (path,yi)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   478
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   479
            (th,lit)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   480
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   481
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   482
      val assumeLit = (false,(R,xs))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   483
      val assumeTh = Thm.assume assumeLit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   484
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   485
      fst (foldl cong (assumeTh,assumeLit) (enumerate ys))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   486
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   487
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   488
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   489
(*   ~(x = y) \/ C                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   490
(* ----------------- symNeq ~(x = y)                                         *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   491
(*   ~(y = x) \/ C                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   492
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   493
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   494
fun symNeq lit th =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   495
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   496
      val (x,y) = Literal.destNeq lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   497
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   498
      if Term.equal x y then th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   499
      else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   500
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   501
          val sub = Subst.fromList [(xVarName,y),(yVarName,x)]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   502
          val symTh = Thm.subst sub symmetry
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   503
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   504
          Thm.resolve lit th symTh
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   505
        end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   506
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   507
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   508
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   509
(* sym (x = y) = symEq (x = y)  /\  sym ~(x = y) = symNeq ~(x = y)           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   510
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   511
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   512
fun sym (lit as (pol,_)) th = if pol then symEq lit th else symNeq lit th;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   513
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   514
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   515
(*   ~(x = x) \/ C                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   516
(* ----------------- removeIrrefl                                            *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   517
(*         C                                                                 *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   518
(*                                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   519
(* where all irreflexive equalities.                                         *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   520
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   521
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   522
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   523
  fun irrefl ((true,_),th) = th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   524
    | irrefl (lit as (false,atm), th) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   525
      case total Atom.destRefl atm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   526
        SOME x => Thm.resolve lit th (Thm.refl x)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   527
      | NONE => th;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   528
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   529
  fun removeIrrefl th = LiteralSet.foldl irrefl th (Thm.clause th);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   530
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   531
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   532
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   533
(*   x = y \/ y = x \/ C                                                     *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   534
(* ----------------------- removeSym                                         *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   535
(*       x = y \/ C                                                          *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   536
(*                                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   537
(* where all duplicate copies of equalities and disequalities are removed.   *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   538
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   539
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   540
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   541
  fun rem (lit as (pol,atm), eqs_th as (eqs,th)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   542
      case total Atom.sym atm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   543
        NONE => eqs_th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   544
      | SOME atm' =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   545
        if LiteralSet.member lit eqs then
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   546
          (eqs, if pol then symEq lit th else symNeq lit th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   547
        else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   548
          (LiteralSet.add eqs (pol,atm'), th);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   549
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   550
  fun removeSym th =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   551
      snd (LiteralSet.foldl rem (LiteralSet.empty,th) (Thm.clause th));
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   552
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   553
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   554
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   555
(*   ~(v = t) \/ C                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   556
(* ----------------- expandAbbrevs                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   557
(*      C[t/v]                                                               *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   558
(*                                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   559
(* where t must not contain any occurrence of the variable v.                *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   560
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   561
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   562
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   563
  fun expand lit =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   564
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   565
        val (x,y) = Literal.destNeq lit
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   566
        val _ = Term.isTypedVar x orelse Term.isTypedVar y orelse
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   567
                raise Error "Rule.expandAbbrevs: no vars"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   568
        val _ = not (Term.equal x y) orelse
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   569
                raise Error "Rule.expandAbbrevs: equal vars"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   570
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   571
        Subst.unify Subst.empty x y
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   572
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   573
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   574
  fun expandAbbrevs th =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   575
      case LiteralSet.firstl (total expand) (Thm.clause th) of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   576
        NONE => removeIrrefl th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   577
      | SOME sub => expandAbbrevs (Thm.subst sub th);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   578
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   579
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   580
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   581
(* simplify = isTautology + expandAbbrevs + removeSym                        *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   582
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   583
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   584
fun simplify th =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   585
    if Thm.isTautology th then NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   586
    else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   587
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   588
        val th' = th
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   589
        val th' = expandAbbrevs th'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   590
        val th' = removeSym th'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   591
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   592
        if Thm.equal th th' then SOME th else simplify th'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   593
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   594
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   595
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   596
(*    C                                                                      *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   597
(* -------- freshVars                                                        *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   598
(*   C[s]                                                                    *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   599
(*                                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   600
(* where s is a renaming substitution chosen so that all of the variables in *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   601
(* C are replaced by fresh variables.                                        *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   602
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   603
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   604
fun freshVars th = Thm.subst (Subst.freshVars (Thm.freeVars th)) th;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   605
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   606
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   607
(*               C                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   608
(* ---------------------------- factor                                       *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   609
(*   C_s_1, C_s_2, ..., C_s_n                                                *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   610
(*                                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   611
(* where each s_i is a substitution that factors C, meaning that the theorem *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   612
(*                                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   613
(*   C_s_i = (removeIrrefl o removeSym o Thm.subst s_i) C                    *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   614
(*                                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   615
(* has fewer literals than C.                                                *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   616
(*                                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   617
(* Also, if s is any substitution that factors C, then one of the s_i will   *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   618
(* result in a theorem C_s_i that strictly subsumes the theorem C_s.         *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   619
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   620
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   621
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   622
  datatype edge =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   623
      FactorEdge of Atom.atom * Atom.atom
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   624
    | ReflEdge of Term.term * Term.term;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   625
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   626
  fun ppEdge (FactorEdge atm_atm') = Print.ppPair Atom.pp Atom.pp atm_atm'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   627
    | ppEdge (ReflEdge tm_tm') = Print.ppPair Term.pp Term.pp tm_tm';
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   628
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   629
  datatype joinStatus =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   630
      Joined
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   631
    | Joinable of Subst.subst
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   632
    | Apart;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   633
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   634
  fun joinEdge sub edge =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   635
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   636
        val result =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   637
            case edge of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   638
              FactorEdge (atm,atm') => total (Atom.unify sub atm) atm'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   639
            | ReflEdge (tm,tm') => total (Subst.unify sub tm) tm'
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
        case result of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   642
          NONE => Apart
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   643
        | SOME sub' =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   644
          if Portable.pointerEqual (sub,sub') then Joined else Joinable sub'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   645
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   646
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   647
  fun updateApart sub =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   648
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   649
        fun update acc [] = SOME acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   650
          | update acc (edge :: edges) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   651
            case joinEdge sub edge of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   652
              Joined => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   653
            | Joinable _ => update (edge :: acc) edges
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   654
            | Apart => update acc edges
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   655
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   656
        update []
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   657
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   658
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   659
  fun addFactorEdge (pol,atm) ((pol',atm'),acc) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   660
      if pol <> pol' then acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   661
      else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   662
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   663
          val edge = FactorEdge (atm,atm')
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   664
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   665
          case joinEdge Subst.empty edge of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   666
            Joined => raise Bug "addFactorEdge: joined"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   667
          | Joinable sub => (sub,edge) :: acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   668
          | Apart => acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   669
        end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   670
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   671
  fun addReflEdge (false,_) acc = acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   672
    | addReflEdge (true,atm) acc =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   673
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   674
        val edge = ReflEdge (Atom.destEq atm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   675
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   676
        case joinEdge Subst.empty edge of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   677
          Joined => raise Bug "addRefl: joined"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   678
        | Joinable _ => edge :: acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   679
        | Apart => acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   680
      end;
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 addIrreflEdge (true,_) acc = acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   683
    | addIrreflEdge (false,atm) acc =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   684
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   685
        val edge = ReflEdge (Atom.destEq atm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   686
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   687
        case joinEdge Subst.empty edge of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   688
          Joined => raise Bug "addRefl: joined"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   689
        | Joinable sub => (sub,edge) :: acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   690
        | Apart => acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   691
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   692
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   693
  fun init_edges acc _ [] =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   694
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   695
        fun init ((apart,sub,edge),(edges,acc)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   696
            (edge :: edges, (apart,sub,edges) :: acc)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   697
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   698
        snd (List.foldl init ([],[]) acc)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   699
      end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   700
    | init_edges acc apart ((sub,edge) :: sub_edges) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   701
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   702
(*MetisDebug
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   703
        val () = if not (Subst.null sub) then ()
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   704
                 else raise Bug "Rule.factor.init_edges: empty subst"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   705
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   706
        val (acc,apart) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   707
            case updateApart sub apart of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   708
              SOME apart' => ((apart',sub,edge) :: acc, edge :: apart)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   709
            | NONE => (acc,apart)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   710
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   711
        init_edges acc apart sub_edges
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   712
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   713
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   714
  fun mk_edges apart sub_edges [] = init_edges [] apart sub_edges
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   715
    | mk_edges apart sub_edges (lit :: lits) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   716
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   717
        val sub_edges = List.foldl (addFactorEdge lit) sub_edges lits
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   718
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   719
        val (apart,sub_edges) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   720
            case total Literal.sym lit of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   721
              NONE => (apart,sub_edges)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   722
            | SOME lit' =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   723
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   724
                val apart = addReflEdge lit apart
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   725
                val sub_edges = addIrreflEdge lit sub_edges
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   726
                val sub_edges = List.foldl (addFactorEdge lit') sub_edges lits
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   727
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   728
                (apart,sub_edges)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   729
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   730
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   731
        mk_edges apart sub_edges lits
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   732
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   733
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   734
  fun fact acc [] = acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   735
    | fact acc ((_,sub,[]) :: others) = fact (sub :: acc) others
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   736
    | fact acc ((apart, sub, edge :: edges) :: others) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   737
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   738
        val others =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   739
            case joinEdge sub edge of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   740
              Joinable sub' =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   741
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   742
                val others = (edge :: apart, sub, edges) :: others
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   743
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   744
                case updateApart sub' apart of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   745
                  NONE => others
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   746
                | SOME apart' => (apart',sub',edges) :: others
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   747
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   748
            | _ => (apart,sub,edges) :: others
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   749
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   750
        fact acc others
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   751
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   752
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   753
  fun factor' cl =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   754
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   755
(*MetisTrace6
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   756
        val () = Print.trace LiteralSet.pp "Rule.factor': cl" cl
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   757
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   758
        val edges = mk_edges [] [] (LiteralSet.toList cl)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   759
(*MetisTrace6
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   760
        val ppEdgesSize = Print.ppMap length Print.ppInt
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   761
        val ppEdgel = Print.ppList ppEdge
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   762
        val ppEdges = Print.ppList (Print.ppTriple ppEdgel Subst.pp ppEdgel)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   763
        val () = Print.trace ppEdgesSize "Rule.factor': |edges|" edges
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   764
        val () = Print.trace ppEdges "Rule.factor': edges" edges
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   765
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   766
        val result = fact [] edges
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   767
(*MetisTrace6
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   768
        val ppResult = Print.ppList Subst.pp
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   769
        val () = Print.trace ppResult "Rule.factor': result" result
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   770
*)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   771
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   772
        result
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   773
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   774
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   775
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   776
fun factor th =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   777
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   778
      fun fact sub = removeSym (Thm.subst sub th)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   779
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   780
      map fact (factor' (Thm.clause th))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   781
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   782
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   783
end