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