src/Tools/Metis/src/Active.sml
changeset 39347 50dec19e682b
parent 39346 d837998f1e60
child 39348 6f9c9899f99f
equal deleted inserted replaced
39346:d837998f1e60 39347:50dec19e682b
     1 (* ========================================================================= *)
       
     2 (* THE ACTIVE SET OF CLAUSES                                                 *)
       
     3 (* Copyright (c) 2002-2006 Joe Hurd, distributed under the BSD License *)
       
     4 (* ========================================================================= *)
       
     5 
       
     6 structure Active :> Active =
       
     7 struct
       
     8 
       
     9 open Useful;
       
    10 
       
    11 (* ------------------------------------------------------------------------- *)
       
    12 (* Helper functions.                                                         *)
       
    13 (* ------------------------------------------------------------------------- *)
       
    14 
       
    15 local
       
    16   fun allFactors red =
       
    17       let
       
    18         fun allClause cl = List.all red (cl :: Clause.factor cl)
       
    19       in
       
    20         List.all allClause
       
    21       end;
       
    22 
       
    23   fun allResolutions red =
       
    24       let
       
    25         fun allClause2 cl_lit cl =
       
    26             let
       
    27               fun allLiteral2 lit =
       
    28                   case total (Clause.resolve cl_lit) (cl,lit) of
       
    29                     NONE => true
       
    30                   | SOME cl => allFactors red [cl]
       
    31             in
       
    32               LiteralSet.all allLiteral2 (Clause.literals cl)
       
    33             end
       
    34 
       
    35         fun allClause1 allCls cl =
       
    36             let
       
    37               val cl = Clause.freshVars cl
       
    38 
       
    39               fun allLiteral1 lit = List.all (allClause2 (cl,lit)) allCls
       
    40             in
       
    41               LiteralSet.all allLiteral1 (Clause.literals cl)
       
    42             end
       
    43       in
       
    44         fn [] => true
       
    45          | allCls as cl :: cls =>
       
    46            allClause1 allCls cl andalso allResolutions red cls
       
    47       end;
       
    48 
       
    49   fun allParamodulations red cls =
       
    50       let
       
    51         fun allClause2 cl_lit_ort_tm cl =
       
    52             let
       
    53               fun allLiteral2 lit =
       
    54                   let
       
    55                     val para = Clause.paramodulate cl_lit_ort_tm
       
    56 
       
    57                     fun allSubterms (path,tm) =
       
    58                         case total para (cl,lit,path,tm) of
       
    59                           NONE => true
       
    60                         | SOME cl => allFactors red [cl]
       
    61                   in
       
    62                     List.all allSubterms (Literal.nonVarTypedSubterms lit)
       
    63                   end
       
    64             in
       
    65               LiteralSet.all allLiteral2 (Clause.literals cl)
       
    66             end
       
    67 
       
    68         fun allClause1 cl =
       
    69             let
       
    70               val cl = Clause.freshVars cl
       
    71 
       
    72               fun allLiteral1 lit =
       
    73                   let
       
    74                     fun allCl2 x = List.all (allClause2 x) cls
       
    75                   in
       
    76                     case total Literal.destEq lit of
       
    77                       NONE => true
       
    78                     | SOME (l,r) =>
       
    79                       allCl2 (cl,lit,Rewrite.LeftToRight,l) andalso
       
    80                       allCl2 (cl,lit,Rewrite.RightToLeft,r)
       
    81                   end
       
    82             in
       
    83               LiteralSet.all allLiteral1 (Clause.literals cl)
       
    84             end
       
    85       in
       
    86         List.all allClause1 cls
       
    87       end;
       
    88 
       
    89   fun redundant {subsume,reduce,rewrite} =
       
    90       let
       
    91         fun simp cl =
       
    92             case Clause.simplify cl of
       
    93               NONE => true
       
    94             | SOME cl =>
       
    95               Subsume.isStrictlySubsumed subsume (Clause.literals cl) orelse
       
    96               let
       
    97                 val cl' = cl
       
    98                 val cl' = Clause.reduce reduce cl'
       
    99                 val cl' = Clause.rewrite rewrite cl'
       
   100               in
       
   101                 not (Clause.equalThms cl cl') andalso simp cl'
       
   102               end
       
   103       in
       
   104         simp
       
   105       end;
       
   106 in
       
   107   fun isSaturated ordering subs cls =
       
   108       let
       
   109 (*TRACE2
       
   110         val ppCls = Parser.ppList Clause.pp
       
   111         val () = Parser.ppTrace ppCls "Active.checkSaturated: clauses" cls
       
   112 *)
       
   113         val red = Units.empty
       
   114         val rw = Rewrite.new (KnuthBendixOrder.compare ordering)
       
   115         val red = redundant {subsume = subs, reduce = red, rewrite = rw}
       
   116       in
       
   117         allFactors red cls andalso
       
   118         allResolutions red cls andalso
       
   119         allParamodulations red cls
       
   120       end;
       
   121 
       
   122   fun checkSaturated ordering subs cls =
       
   123       if isSaturated ordering subs cls then () else raise Bug "unsaturated";
       
   124 end;
       
   125 
       
   126 (* ------------------------------------------------------------------------- *)
       
   127 (* A type of active clause sets.                                             *)
       
   128 (* ------------------------------------------------------------------------- *)
       
   129 
       
   130 type simplify = {subsume : bool, reduce : bool, rewrite : bool};
       
   131 
       
   132 type parameters =
       
   133      {clause : Clause.parameters,
       
   134       prefactor : simplify,
       
   135       postfactor : simplify};
       
   136 
       
   137 datatype active =
       
   138     Active of
       
   139       {parameters : parameters,
       
   140        clauses : Clause.clause IntMap.map,
       
   141        units : Units.units,
       
   142        rewrite : Rewrite.rewrite,
       
   143        subsume : Clause.clause Subsume.subsume,
       
   144        literals : (Clause.clause * Literal.literal) LiteralNet.literalNet,
       
   145        equations :
       
   146          (Clause.clause * Literal.literal * Rewrite.orient * Term.term)
       
   147          TermNet.termNet,
       
   148        subterms :
       
   149          (Clause.clause * Literal.literal * Term.path * Term.term)
       
   150          TermNet.termNet,
       
   151        allSubterms : (Clause.clause * Term.term) TermNet.termNet};
       
   152 
       
   153 fun getSubsume (Active {subsume = s, ...}) = s;
       
   154 
       
   155 fun setRewrite active rewrite =
       
   156     let
       
   157       val Active
       
   158             {parameters,clauses,units,subsume,literals,equations,
       
   159              subterms,allSubterms,...} = active
       
   160     in
       
   161       Active
       
   162         {parameters = parameters, clauses = clauses, units = units,
       
   163          rewrite = rewrite, subsume = subsume, literals = literals,
       
   164          equations = equations, subterms = subterms, allSubterms = allSubterms}
       
   165     end;
       
   166 
       
   167 (* ------------------------------------------------------------------------- *)
       
   168 (* Basic operations.                                                         *)
       
   169 (* ------------------------------------------------------------------------- *)
       
   170 
       
   171 val maxSimplify : simplify = {subsume = true, reduce = true, rewrite = true};
       
   172 
       
   173 val default : parameters =
       
   174     {clause = Clause.default,
       
   175      prefactor = maxSimplify,
       
   176      postfactor = maxSimplify};
       
   177 
       
   178 fun empty parameters =
       
   179     let
       
   180       val {clause,...} = parameters
       
   181       val {ordering,...} = clause
       
   182     in
       
   183       Active
       
   184         {parameters = parameters,
       
   185          clauses = IntMap.new (),
       
   186          units = Units.empty,
       
   187          rewrite = Rewrite.new (KnuthBendixOrder.compare ordering),
       
   188          subsume = Subsume.new (),
       
   189          literals = LiteralNet.new {fifo = false},
       
   190          equations = TermNet.new {fifo = false},
       
   191          subterms = TermNet.new {fifo = false},
       
   192          allSubterms = TermNet.new {fifo = false}}
       
   193     end;
       
   194 
       
   195 fun size (Active {clauses,...}) = IntMap.size clauses;
       
   196 
       
   197 fun clauses (Active {clauses = cls, ...}) =
       
   198     let
       
   199       fun add (_,cl,acc) = cl :: acc
       
   200     in
       
   201       IntMap.foldr add [] cls
       
   202     end;
       
   203 
       
   204 fun saturated active =
       
   205     let
       
   206       fun remove (cl,(cls,subs)) =
       
   207           let
       
   208             val lits = Clause.literals cl
       
   209           in
       
   210             if Subsume.isStrictlySubsumed subs lits then (cls,subs)
       
   211             else (cl :: cls, Subsume.insert subs (lits,()))
       
   212           end
       
   213 
       
   214       val cls = clauses active
       
   215       val (cls,_) = foldl remove ([], Subsume.new ()) cls
       
   216       val (cls,subs) = foldl remove ([], Subsume.new ()) cls
       
   217 
       
   218 (*DEBUG
       
   219       val Active {parameters,...} = active
       
   220       val {clause,...} = parameters
       
   221       val {ordering,...} = clause
       
   222       val () = checkSaturated ordering subs cls
       
   223 *)
       
   224     in
       
   225       cls
       
   226     end;
       
   227 
       
   228 (* ------------------------------------------------------------------------- *)
       
   229 (* Pretty printing.                                                          *)
       
   230 (* ------------------------------------------------------------------------- *)
       
   231 
       
   232 val pp =
       
   233     let
       
   234       fun toStr active = "Active{" ^ Int.toString (size active) ^ "}"
       
   235     in
       
   236       Parser.ppMap toStr Parser.ppString
       
   237     end;
       
   238 
       
   239 (*DEBUG
       
   240 local
       
   241   open Parser;
       
   242 
       
   243   fun ppField f ppA p a =
       
   244       (beginBlock p Inconsistent 2;
       
   245        addString p (f ^ " =");
       
   246        addBreak p (1,0);
       
   247        ppA p a;
       
   248        endBlock p);
       
   249 
       
   250   val ppClauses =
       
   251       ppField "clauses"
       
   252         (Parser.ppMap IntMap.toList
       
   253            (Parser.ppList (Parser.ppPair Parser.ppInt Clause.pp)));
       
   254 
       
   255   val ppRewrite = ppField "rewrite" Rewrite.pp;
       
   256 
       
   257   val ppSubterms =
       
   258       ppField "subterms"
       
   259         (TermNet.pp
       
   260            (Parser.ppMap (fn (c,l,p,t) => ((Clause.id c, l, p), t))
       
   261               (Parser.ppPair
       
   262                  (Parser.ppTriple Parser.ppInt Literal.pp Term.ppPath)
       
   263                  Term.pp)));
       
   264 in
       
   265   fun pp p (Active {clauses,rewrite,subterms,...}) =
       
   266       (beginBlock p Inconsistent 2;
       
   267        addString p "Active";
       
   268        addBreak p (1,0);
       
   269        beginBlock p Inconsistent 1;
       
   270        addString p "{";
       
   271        ppClauses p clauses;
       
   272        addString p ",";
       
   273        addBreak p (1,0);
       
   274        ppRewrite p rewrite;
       
   275 (*TRACE5
       
   276        addString p ",";
       
   277        addBreak p (1,0);
       
   278        ppSubterms p subterms;
       
   279 *)
       
   280        endBlock p;
       
   281        addString p "}";
       
   282        endBlock p);
       
   283 end;
       
   284 *)
       
   285 
       
   286 val toString = Parser.toString pp;
       
   287 
       
   288 (* ------------------------------------------------------------------------- *)
       
   289 (* Simplify clauses.                                                         *)
       
   290 (* ------------------------------------------------------------------------- *)
       
   291 
       
   292 fun simplify simp units rewr subs =
       
   293     let
       
   294       val {subsume = s, reduce = r, rewrite = w} = simp
       
   295 
       
   296       fun rewrite cl =
       
   297           let
       
   298             val cl' = Clause.rewrite rewr cl
       
   299           in
       
   300             if Clause.equalThms cl cl' then SOME cl else Clause.simplify cl'
       
   301           end
       
   302     in
       
   303       fn cl =>
       
   304          case Clause.simplify cl of
       
   305            NONE => NONE
       
   306          | SOME cl =>
       
   307            case (if w then rewrite cl else SOME cl) of
       
   308              NONE => NONE
       
   309            | SOME cl =>
       
   310              let
       
   311                val cl = if r then Clause.reduce units cl else cl
       
   312              in
       
   313                if s andalso Clause.subsumes subs cl then NONE else SOME cl
       
   314              end
       
   315     end;
       
   316 
       
   317 (*DEBUG
       
   318 val simplify = fn simp => fn units => fn rewr => fn subs => fn cl =>
       
   319     let
       
   320       fun traceCl s = Parser.ppTrace Clause.pp ("Active.simplify: " ^ s)
       
   321 (*TRACE4
       
   322       val ppClOpt = Parser.ppOption Clause.pp
       
   323       val () = traceCl "cl" cl
       
   324 *)
       
   325       val cl' = simplify simp units rewr subs cl
       
   326 (*TRACE4
       
   327       val () = Parser.ppTrace ppClOpt "Active.simplify: cl'" cl'
       
   328 *)
       
   329       val () =
       
   330           case cl' of
       
   331             NONE => ()
       
   332           | SOME cl' =>
       
   333             case
       
   334               (case simplify simp units rewr subs cl' of
       
   335                  NONE => SOME ("away", K ())
       
   336                | SOME cl'' =>
       
   337                  if Clause.equalThms cl' cl'' then NONE
       
   338                  else SOME ("further", fn () => traceCl "cl''" cl'')) of
       
   339               NONE => ()
       
   340             | SOME (e,f) =>
       
   341               let
       
   342                 val () = traceCl "cl" cl
       
   343                 val () = traceCl "cl'" cl'
       
   344                 val () = f ()
       
   345               in
       
   346                 raise
       
   347                   Bug
       
   348                     ("Active.simplify: clause should have been simplified "^e)
       
   349               end
       
   350     in
       
   351       cl'
       
   352     end;
       
   353 *)
       
   354 
       
   355 fun simplifyActive simp active =
       
   356     let
       
   357       val Active {units,rewrite,subsume,...} = active
       
   358     in
       
   359       simplify simp units rewrite subsume
       
   360     end;
       
   361 
       
   362 (* ------------------------------------------------------------------------- *)
       
   363 (* Add a clause into the active set.                                         *)
       
   364 (* ------------------------------------------------------------------------- *)
       
   365 
       
   366 fun addUnit units cl =
       
   367     let
       
   368       val th = Clause.thm cl
       
   369     in
       
   370       case total Thm.destUnit th of
       
   371         SOME lit => Units.add units (lit,th)
       
   372       | NONE => units
       
   373     end;
       
   374 
       
   375 fun addRewrite rewrite cl =
       
   376     let
       
   377       val th = Clause.thm cl
       
   378     in
       
   379       case total Thm.destUnitEq th of
       
   380         SOME l_r => Rewrite.add rewrite (Clause.id cl, (l_r,th))
       
   381       | NONE => rewrite
       
   382     end;
       
   383 
       
   384 fun addSubsume subsume cl = Subsume.insert subsume (Clause.literals cl, cl);
       
   385 
       
   386 fun addLiterals literals cl =
       
   387     let
       
   388       fun add (lit as (_,atm), literals) =
       
   389           if Atom.isEq atm then literals
       
   390           else LiteralNet.insert literals (lit,(cl,lit))
       
   391     in
       
   392       LiteralSet.foldl add literals (Clause.largestLiterals cl)
       
   393     end;
       
   394 
       
   395 fun addEquations equations cl =
       
   396     let
       
   397       fun add ((lit,ort,tm),equations) =
       
   398           TermNet.insert equations (tm,(cl,lit,ort,tm))
       
   399     in
       
   400       foldl add equations (Clause.largestEquations cl)
       
   401     end;
       
   402 
       
   403 fun addSubterms subterms cl =
       
   404     let
       
   405       fun add ((lit,path,tm),subterms) =
       
   406           TermNet.insert subterms (tm,(cl,lit,path,tm))
       
   407     in
       
   408       foldl add subterms (Clause.largestSubterms cl)
       
   409     end;
       
   410 
       
   411 fun addAllSubterms allSubterms cl =
       
   412     let
       
   413       fun add ((_,_,tm),allSubterms) =
       
   414           TermNet.insert allSubterms (tm,(cl,tm))
       
   415     in
       
   416       foldl add allSubterms (Clause.allSubterms cl)
       
   417     end;
       
   418 
       
   419 fun addClause active cl =
       
   420     let
       
   421       val Active
       
   422             {parameters,clauses,units,rewrite,subsume,literals,
       
   423              equations,subterms,allSubterms} = active
       
   424       val clauses = IntMap.insert clauses (Clause.id cl, cl)
       
   425       and subsume = addSubsume subsume cl
       
   426       and literals = addLiterals literals cl
       
   427       and equations = addEquations equations cl
       
   428       and subterms = addSubterms subterms cl
       
   429       and allSubterms = addAllSubterms allSubterms cl
       
   430     in
       
   431       Active
       
   432         {parameters = parameters, clauses = clauses, units = units,
       
   433          rewrite = rewrite, subsume = subsume, literals = literals,
       
   434          equations = equations, subterms = subterms,
       
   435          allSubterms = allSubterms}
       
   436     end;
       
   437 
       
   438 fun addFactorClause active cl =
       
   439     let
       
   440       val Active
       
   441             {parameters,clauses,units,rewrite,subsume,literals,
       
   442              equations,subterms,allSubterms} = active
       
   443       val units = addUnit units cl
       
   444       and rewrite = addRewrite rewrite cl
       
   445     in
       
   446       Active
       
   447         {parameters = parameters, clauses = clauses, units = units,
       
   448          rewrite = rewrite, subsume = subsume, literals = literals,
       
   449          equations = equations, subterms = subterms, allSubterms = allSubterms}
       
   450     end;
       
   451 
       
   452 (* ------------------------------------------------------------------------- *)
       
   453 (* Derive (unfactored) consequences of a clause.                             *)
       
   454 (* ------------------------------------------------------------------------- *)
       
   455 
       
   456 fun deduceResolution literals cl (lit as (_,atm), acc) =
       
   457     let
       
   458       fun resolve (cl_lit,acc) =
       
   459           case total (Clause.resolve cl_lit) (cl,lit) of
       
   460             SOME cl' => cl' :: acc
       
   461           | NONE => acc
       
   462 (*TRACE4
       
   463       val () = Parser.ppTrace Literal.pp "Active.deduceResolution: lit" lit
       
   464 *)
       
   465     in
       
   466       if Atom.isEq atm then acc
       
   467       else foldl resolve acc (LiteralNet.unify literals (Literal.negate lit))
       
   468     end;
       
   469 
       
   470 fun deduceParamodulationWith subterms cl ((lit,ort,tm),acc) =
       
   471     let
       
   472       fun para (cl_lit_path_tm,acc) =
       
   473           case total (Clause.paramodulate (cl,lit,ort,tm)) cl_lit_path_tm of
       
   474             SOME cl' => cl' :: acc
       
   475           | NONE => acc
       
   476     in
       
   477       foldl para acc (TermNet.unify subterms tm)
       
   478     end;
       
   479 
       
   480 fun deduceParamodulationInto equations cl ((lit,path,tm),acc) =
       
   481     let
       
   482       fun para (cl_lit_ort_tm,acc) =
       
   483           case total (Clause.paramodulate cl_lit_ort_tm) (cl,lit,path,tm) of
       
   484             SOME cl' => cl' :: acc
       
   485           | NONE => acc
       
   486     in
       
   487       foldl para acc (TermNet.unify equations tm)
       
   488     end;
       
   489 
       
   490 fun deduce active cl =
       
   491     let
       
   492       val Active {parameters,literals,equations,subterms,...} = active
       
   493 
       
   494       val lits = Clause.largestLiterals cl
       
   495       val eqns = Clause.largestEquations cl
       
   496       val subtms =
       
   497           if TermNet.null equations then [] else Clause.largestSubterms cl
       
   498 
       
   499       val acc = []
       
   500       val acc = LiteralSet.foldl (deduceResolution literals cl) acc lits
       
   501       val acc = foldl (deduceParamodulationWith subterms cl) acc eqns
       
   502       val acc = foldl (deduceParamodulationInto equations cl) acc subtms
       
   503     in
       
   504       rev acc
       
   505     end;
       
   506 
       
   507 (* ------------------------------------------------------------------------- *)
       
   508 (* Extract clauses from the active set that can be simplified.               *)
       
   509 (* ------------------------------------------------------------------------- *)
       
   510 
       
   511 local
       
   512   fun clause_rewritables active =
       
   513       let
       
   514         val Active {clauses,rewrite,...} = active
       
   515 
       
   516         fun rewr (id,cl,ids) =
       
   517             let
       
   518               val cl' = Clause.rewrite rewrite cl
       
   519             in
       
   520               if Clause.equalThms cl cl' then ids else IntSet.add ids id
       
   521             end
       
   522       in
       
   523         IntMap.foldr rewr IntSet.empty clauses
       
   524       end;
       
   525 
       
   526   fun orderedRedexResidues (((l,r),_),ort) =
       
   527       case ort of
       
   528         NONE => []
       
   529       | SOME Rewrite.LeftToRight => [(l,r,true)]
       
   530       | SOME Rewrite.RightToLeft => [(r,l,true)];
       
   531 
       
   532   fun unorderedRedexResidues (((l,r),_),ort) =
       
   533       case ort of
       
   534         NONE => [(l,r,false),(r,l,false)]
       
   535       | SOME _ => [];
       
   536 
       
   537   fun rewrite_rewritables active rewr_ids =
       
   538       let
       
   539         val Active {parameters,rewrite,clauses,allSubterms,...} = active
       
   540         val {clause = {ordering,...}, ...} = parameters
       
   541         val order = KnuthBendixOrder.compare ordering
       
   542 
       
   543         fun addRewr (id,acc) =
       
   544             if IntMap.inDomain id clauses then IntSet.add acc id else acc
       
   545 
       
   546         fun addReduce ((l,r,ord),acc) =
       
   547             let
       
   548               fun isValidRewr tm =
       
   549                   case total (Subst.match Subst.empty l) tm of
       
   550                     NONE => false
       
   551                   | SOME sub =>
       
   552                     ord orelse
       
   553                     let
       
   554                       val tm' = Subst.subst (Subst.normalize sub) r
       
   555                     in
       
   556                       order (tm,tm') = SOME GREATER
       
   557                     end
       
   558                     
       
   559               fun addRed ((cl,tm),acc) =
       
   560                   let
       
   561 (*TRACE5
       
   562                     val () = Parser.ppTrace Clause.pp "Active.addRed: cl" cl
       
   563                     val () = Parser.ppTrace Term.pp "Active.addRed: tm" tm
       
   564 *)
       
   565                     val id = Clause.id cl
       
   566                   in
       
   567                     if IntSet.member id acc then acc
       
   568                     else if not (isValidRewr tm) then acc
       
   569                     else IntSet.add acc id
       
   570                   end
       
   571 
       
   572 (*TRACE5
       
   573               val () = Parser.ppTrace Term.pp "Active.addReduce: l" l
       
   574               val () = Parser.ppTrace Term.pp "Active.addReduce: r" r
       
   575               val () = Parser.ppTrace Parser.ppBool "Active.addReduce: ord" ord
       
   576 *)
       
   577             in
       
   578               List.foldl addRed acc (TermNet.matched allSubterms l)
       
   579             end
       
   580               
       
   581         fun addEquation redexResidues (id,acc) =
       
   582             case Rewrite.peek rewrite id of
       
   583               NONE => acc
       
   584             | SOME eqn_ort => List.foldl addReduce acc (redexResidues eqn_ort)
       
   585 
       
   586         val addOrdered = addEquation orderedRedexResidues
       
   587 
       
   588         val addUnordered = addEquation unorderedRedexResidues
       
   589 
       
   590         val ids = IntSet.empty
       
   591         val ids = List.foldl addRewr ids rewr_ids
       
   592         val ids = List.foldl addOrdered ids rewr_ids
       
   593         val ids = List.foldl addUnordered ids rewr_ids
       
   594       in
       
   595         ids
       
   596       end;
       
   597 
       
   598   fun choose_clause_rewritables active ids = size active <= length ids
       
   599 
       
   600   fun rewritables active ids =
       
   601       if choose_clause_rewritables active ids then clause_rewritables active
       
   602       else rewrite_rewritables active ids;
       
   603 
       
   604 (*DEBUG
       
   605   val rewritables = fn active => fn ids =>
       
   606       let
       
   607         val clause_ids = clause_rewritables active
       
   608         val rewrite_ids = rewrite_rewritables active ids
       
   609 
       
   610         val () =
       
   611             if IntSet.equal rewrite_ids clause_ids then ()
       
   612             else
       
   613               let
       
   614                 val ppIdl = Parser.ppList Parser.ppInt
       
   615                 val ppIds = Parser.ppMap IntSet.toList ppIdl
       
   616                 val () = Parser.ppTrace pp "Active.rewritables: active" active
       
   617                 val () = Parser.ppTrace ppIdl "Active.rewritables: ids" ids
       
   618                 val () = Parser.ppTrace ppIds
       
   619                            "Active.rewritables: clause_ids" clause_ids
       
   620                 val () = Parser.ppTrace ppIds
       
   621                            "Active.rewritables: rewrite_ids" rewrite_ids
       
   622               in
       
   623                 raise Bug "Active.rewritables: ~(rewrite_ids SUBSET clause_ids)"
       
   624               end
       
   625       in
       
   626         if choose_clause_rewritables active ids then clause_ids else rewrite_ids
       
   627       end;
       
   628 *)
       
   629 
       
   630   fun delete active ids =
       
   631       if IntSet.null ids then active
       
   632       else
       
   633         let
       
   634           fun idPred id = not (IntSet.member id ids)
       
   635                           
       
   636           fun clausePred cl = idPred (Clause.id cl)
       
   637                               
       
   638           val Active
       
   639                 {parameters,clauses,units,rewrite,subsume,literals,
       
   640                  equations,subterms,allSubterms} = active
       
   641 
       
   642           val clauses = IntMap.filter (idPred o fst) clauses
       
   643           and subsume = Subsume.filter clausePred subsume
       
   644           and literals = LiteralNet.filter (clausePred o #1) literals
       
   645           and equations = TermNet.filter (clausePred o #1) equations
       
   646           and subterms = TermNet.filter (clausePred o #1) subterms
       
   647           and allSubterms = TermNet.filter (clausePred o fst) allSubterms
       
   648         in
       
   649           Active
       
   650             {parameters = parameters, clauses = clauses, units = units,
       
   651              rewrite = rewrite, subsume = subsume, literals = literals,
       
   652              equations = equations, subterms = subterms,
       
   653              allSubterms = allSubterms}
       
   654         end;
       
   655 in
       
   656   fun extract_rewritables (active as Active {clauses,rewrite,...}) =
       
   657       if Rewrite.isReduced rewrite then (active,[])
       
   658       else
       
   659         let
       
   660 (*TRACE3
       
   661           val () = trace "Active.extract_rewritables: inter-reducing\n"
       
   662 *)
       
   663           val (rewrite,ids) = Rewrite.reduce' rewrite
       
   664           val active = setRewrite active rewrite
       
   665           val ids = rewritables active ids
       
   666           val cls = IntSet.transform (IntMap.get clauses) ids
       
   667 (*TRACE3
       
   668           val ppCls = Parser.ppList Clause.pp
       
   669           val () = Parser.ppTrace ppCls "Active.extract_rewritables: cls" cls
       
   670 *)
       
   671         in
       
   672           (delete active ids, cls)
       
   673         end
       
   674 (*DEBUG
       
   675         handle Error err =>
       
   676           raise Bug ("Active.extract_rewritables: shouldn't fail\n" ^ err);
       
   677 *)
       
   678 end;
       
   679 
       
   680 (* ------------------------------------------------------------------------- *)
       
   681 (* Factor clauses.                                                           *)
       
   682 (* ------------------------------------------------------------------------- *)
       
   683 
       
   684 local
       
   685   fun prefactor_simplify active subsume =
       
   686       let
       
   687         val Active {parameters,units,rewrite,...} = active
       
   688         val {prefactor,...} = parameters
       
   689       in
       
   690         simplify prefactor units rewrite subsume
       
   691       end;
       
   692 
       
   693   fun postfactor_simplify active subsume =
       
   694       let
       
   695         val Active {parameters,units,rewrite,...} = active
       
   696         val {postfactor,...} = parameters
       
   697       in
       
   698         simplify postfactor units rewrite subsume
       
   699       end;
       
   700 
       
   701   val sort_utilitywise =
       
   702       let
       
   703         fun utility cl =
       
   704             case LiteralSet.size (Clause.literals cl) of
       
   705               0 => ~1
       
   706             | 1 => if Thm.isUnitEq (Clause.thm cl) then 0 else 1
       
   707             | n => n
       
   708       in
       
   709         sortMap utility Int.compare
       
   710       end;
       
   711 
       
   712   fun factor_add (cl, active_subsume_acc as (active,subsume,acc)) =
       
   713       case postfactor_simplify active subsume cl of
       
   714         NONE => active_subsume_acc
       
   715       | SOME cl =>
       
   716         let
       
   717           val active = addFactorClause active cl
       
   718           and subsume = addSubsume subsume cl
       
   719           and acc = cl :: acc
       
   720         in
       
   721           (active,subsume,acc)
       
   722         end;
       
   723 
       
   724   fun factor1 (cl, active_subsume_acc as (active,subsume,_)) =
       
   725       case prefactor_simplify active subsume cl of
       
   726         NONE => active_subsume_acc
       
   727       | SOME cl =>
       
   728         let
       
   729           val cls = sort_utilitywise (cl :: Clause.factor cl)
       
   730         in
       
   731           foldl factor_add active_subsume_acc cls
       
   732         end;
       
   733 
       
   734   fun factor' active acc [] = (active, rev acc)
       
   735     | factor' active acc cls =
       
   736       let
       
   737         val cls = sort_utilitywise cls
       
   738         val subsume = getSubsume active
       
   739         val (active,_,acc) = foldl factor1 (active,subsume,acc) cls
       
   740         val (active,cls) = extract_rewritables active
       
   741       in
       
   742         factor' active acc cls
       
   743       end;
       
   744 in
       
   745   fun factor active cls = factor' active [] cls;
       
   746 end;
       
   747 
       
   748 (*TRACE4
       
   749 val factor = fn active => fn cls =>
       
   750     let
       
   751       val ppCls = Parser.ppList Clause.pp
       
   752       val () = Parser.ppTrace ppCls "Active.factor: cls" cls
       
   753       val (active,cls') = factor active cls
       
   754       val () = Parser.ppTrace ppCls "Active.factor: cls'" cls'
       
   755     in
       
   756       (active,cls')
       
   757     end;
       
   758 *)
       
   759 
       
   760 (* ------------------------------------------------------------------------- *)
       
   761 (* Create a new active clause set and initialize clauses.                    *)
       
   762 (* ------------------------------------------------------------------------- *)
       
   763 
       
   764 fun new parameters ths =
       
   765     let
       
   766       val {clause,...} = parameters
       
   767 
       
   768       fun mk_clause th =
       
   769           Clause.mk {parameters = clause, id = Clause.newId (), thm = th}
       
   770 
       
   771       val cls = map mk_clause ths
       
   772     in
       
   773       factor (empty parameters) cls
       
   774     end;
       
   775 
       
   776 (* ------------------------------------------------------------------------- *)
       
   777 (* Add a clause into the active set and deduce all consequences.             *)
       
   778 (* ------------------------------------------------------------------------- *)
       
   779 
       
   780 fun add active cl =
       
   781     case simplifyActive maxSimplify active cl of
       
   782       NONE => (active,[])
       
   783     | SOME cl' =>
       
   784       if Clause.isContradiction cl' then (active,[cl'])
       
   785       else if not (Clause.equalThms cl cl') then factor active [cl']
       
   786       else
       
   787         let
       
   788 (*TRACE3
       
   789           val () = Parser.ppTrace Clause.pp "Active.add: cl" cl
       
   790 *)
       
   791           val active = addClause active cl
       
   792           val cl = Clause.freshVars cl
       
   793           val cls = deduce active cl
       
   794           val (active,cls) = factor active cls
       
   795 (*TRACE2
       
   796           val ppCls = Parser.ppList Clause.pp
       
   797           val () = Parser.ppTrace ppCls "Active.add: cls" cls
       
   798 *)
       
   799         in
       
   800           (active,cls)
       
   801         end;
       
   802 
       
   803 end