src/Tools/Metis/src/Waiting.sml
changeset 39353 7f11d833d65b
parent 25430 372d6749f00e
parent 39349 2d0a4361c3ef
child 39407 9e6faecea412
equal deleted inserted replaced
39313:41ce0b56d858 39353:7f11d833d65b
     1 (* ========================================================================= *)
     1 (* ========================================================================= *)
     2 (* THE WAITING SET OF CLAUSES                                                *)
     2 (* THE WAITING SET OF CLAUSES                                                *)
     3 (* Copyright (c) 2002-2007 Joe Hurd, distributed under the BSD License *)
     3 (* Copyright (c) 2002-2007 Joe Hurd, distributed under the BSD License       *)
     4 (* ========================================================================= *)
     4 (* ========================================================================= *)
     5 
     5 
     6 structure Waiting :> Waiting =
     6 structure Waiting :> Waiting =
     7 struct
     7 struct
     8 
     8 
    10 
    10 
    11 (* ------------------------------------------------------------------------- *)
    11 (* ------------------------------------------------------------------------- *)
    12 (* A type of waiting sets of clauses.                                        *)
    12 (* A type of waiting sets of clauses.                                        *)
    13 (* ------------------------------------------------------------------------- *)
    13 (* ------------------------------------------------------------------------- *)
    14 
    14 
    15 (* The parameter type controls the heuristics for clause selection.          *)
    15 type weight = real;
    16 (* Increasing any of the *Weight parameters will favour clauses with low     *)
    16 
    17 (* values of that field.                                                     *)
    17 type modelParameters =
    18 
    18      {model : Model.parameters,
    19 (* Note that there is an extra parameter of inference distance from the      *)
    19       initialPerturbations : int,
    20 (* starting axioms (a.k.a. time) which has a fixed weight of 1, so all       *)
    20       maxChecks : int option,
    21 (* the other parameters should be set relative to this baseline.             *)
    21       perturbations : int,
    22 
    22       weight : weight}
    23 (* The first two parameters, symbolsWeight and literalsWeight, control the   *)
       
    24 (* time:weight ratio, i.e., whether to favour clauses derived in a few       *)
       
    25 (* steps from the axioms (time) or whether to favour small clauses (weight). *)
       
    26 (* Small can be a combination of low number of symbols (the symbolWeight     *)
       
    27 (* parameter) or literals (the literalsWeight parameter).                    *)
       
    28 
       
    29 (* modelsWeight controls the semantic guidance. Increasing this parameter    *)
       
    30 (* favours clauses that return false more often when interpreted             *)
       
    31 (* modelChecks times over the given list of models.                          *)
       
    32 
    23 
    33 type parameters =
    24 type parameters =
    34      {symbolsWeight : real,
    25      {symbolsWeight : weight,
    35       literalsWeight : real,
    26       variablesWeight : weight,
    36       modelsWeight : real,
    27       literalsWeight : weight,
    37       modelChecks : int,
    28       models : modelParameters list};
    38       models : Model.parameters list};
       
    39 
    29 
    40 type distance = real;
    30 type distance = real;
    41 
       
    42 type weight = real;
       
    43 
    31 
    44 datatype waiting =
    32 datatype waiting =
    45     Waiting of
    33     Waiting of
    46       {parameters : parameters,
    34       {parameters : parameters,
    47        clauses : (weight * (distance * Clause.clause)) Heap.heap,
    35        clauses : (weight * (distance * Clause.clause)) Heap.heap,
    49 
    37 
    50 (* ------------------------------------------------------------------------- *)
    38 (* ------------------------------------------------------------------------- *)
    51 (* Basic operations.                                                         *)
    39 (* Basic operations.                                                         *)
    52 (* ------------------------------------------------------------------------- *)
    40 (* ------------------------------------------------------------------------- *)
    53 
    41 
       
    42 val defaultModels : modelParameters list =
       
    43     [{model = Model.default,
       
    44       initialPerturbations = 100,
       
    45       maxChecks = SOME 20,
       
    46       perturbations = 0,
       
    47       weight = 1.0}];
       
    48 
    54 val default : parameters =
    49 val default : parameters =
    55      {symbolsWeight = 1.0,
    50      {symbolsWeight = 1.0,
    56       literalsWeight = 0.0,
    51       literalsWeight = 1.0,
    57       modelsWeight = 0.0,
    52       variablesWeight = 1.0,
    58       modelChecks = 20,
    53       models = defaultModels};
    59       models = []};
       
    60 
    54 
    61 fun size (Waiting {clauses,...}) = Heap.size clauses;
    55 fun size (Waiting {clauses,...}) = Heap.size clauses;
    62 
    56 
    63 val pp =
    57 val pp =
    64     Parser.ppMap
    58     Print.ppMap
    65       (fn w => "Waiting{" ^ Int.toString (size w) ^ "}")
    59       (fn w => "Waiting{" ^ Int.toString (size w) ^ "}")
    66       Parser.ppString;
    60       Print.ppString;
    67 
    61 
    68 (*DEBUG
    62 (*MetisDebug
    69 val pp =
    63 val pp =
    70     Parser.ppMap
    64     Print.ppMap
    71       (fn Waiting {clauses,...} =>
    65       (fn Waiting {clauses,...} =>
    72           map (fn (w,(_,cl)) => (w, Clause.id cl, cl)) (Heap.toList clauses))
    66           map (fn (w,(_,cl)) => (w, Clause.id cl, cl)) (Heap.toList clauses))
    73       (Parser.ppList (Parser.ppTriple Parser.ppReal Parser.ppInt Clause.pp));
    67       (Print.ppList (Print.ppTriple Print.ppReal Print.ppInt Clause.pp));
    74 *)
    68 *)
       
    69 
       
    70 (* ------------------------------------------------------------------------- *)
       
    71 (* Perturbing the models.                                                    *)
       
    72 (* ------------------------------------------------------------------------- *)
       
    73 
       
    74 type modelClause = NameSet.set * Thm.clause;
       
    75 
       
    76 fun mkModelClause cl =
       
    77     let
       
    78       val lits = Clause.literals cl
       
    79       val fvs = LiteralSet.freeVars lits
       
    80     in
       
    81       (fvs,lits)
       
    82     end;
       
    83 
       
    84 val mkModelClauses = map mkModelClause;
       
    85 
       
    86 fun perturbModel M cls =
       
    87     if null cls then K ()
       
    88     else
       
    89       let
       
    90         val N = {size = Model.size M}
       
    91 
       
    92         fun perturbClause (fv,cl) =
       
    93             let
       
    94               val V = Model.randomValuation N fv
       
    95             in
       
    96               if Model.interpretClause M V cl then ()
       
    97               else Model.perturbClause M V cl
       
    98             end
       
    99 
       
   100         fun perturbClauses () = app perturbClause cls
       
   101       in
       
   102         fn n => funpow n perturbClauses ()
       
   103       end;
       
   104 
       
   105 fun initialModel axioms conjecture parm =
       
   106     let
       
   107       val {model,initialPerturbations,...} : modelParameters = parm
       
   108       val m = Model.new model
       
   109       val () = perturbModel m conjecture initialPerturbations
       
   110       val () = perturbModel m axioms initialPerturbations
       
   111     in
       
   112       m
       
   113     end;
       
   114 
       
   115 fun checkModels parms models (fv,cl) =
       
   116     let
       
   117       fun check ((parm,model),z) =
       
   118           let
       
   119             val {maxChecks,weight,...} : modelParameters = parm
       
   120             val n = {maxChecks = maxChecks}
       
   121             val {T,F} = Model.check Model.interpretClause n model fv cl
       
   122           in
       
   123             Math.pow (1.0 + Real.fromInt T / Real.fromInt (T + F), weight) * z
       
   124           end
       
   125     in
       
   126       List.foldl check 1.0 (zip parms models)
       
   127     end;
       
   128 
       
   129 fun perturbModels parms models cls =
       
   130     let
       
   131       fun perturb (parm,model) =
       
   132           let
       
   133             val {perturbations,...} : modelParameters = parm
       
   134           in
       
   135             perturbModel model cls perturbations
       
   136           end
       
   137     in
       
   138       app perturb (zip parms models)
       
   139     end;
    75 
   140 
    76 (* ------------------------------------------------------------------------- *)
   141 (* ------------------------------------------------------------------------- *)
    77 (* Clause weights.                                                           *)
   142 (* Clause weights.                                                           *)
    78 (* ------------------------------------------------------------------------- *)
   143 (* ------------------------------------------------------------------------- *)
    79 
   144 
    80 local
   145 local
    81   fun clauseSymbols cl = Real.fromInt (LiteralSet.typedSymbols cl);
   146   fun clauseSymbols cl = Real.fromInt (LiteralSet.typedSymbols cl);
    82 
   147 
       
   148   fun clauseVariables cl =
       
   149       Real.fromInt (NameSet.size (LiteralSet.freeVars cl) + 1);
       
   150 
    83   fun clauseLiterals cl = Real.fromInt (LiteralSet.size cl);
   151   fun clauseLiterals cl = Real.fromInt (LiteralSet.size cl);
    84 
   152 
    85   fun clauseSat modelChecks models cl =
   153   fun clausePriority cl = 1e~12 * Real.fromInt (Clause.id cl);
    86       let
       
    87         fun g {T,F} = (Real.fromInt T / Real.fromInt (T + F)) + 1.0
       
    88         fun f (m,z) = g (Model.checkClause {maxChecks = modelChecks} m cl) * z
       
    89       in
       
    90         foldl f 1.0 models
       
    91       end;
       
    92 
       
    93   fun priority cl = 1e~12 * Real.fromInt (Clause.id cl);
       
    94 in
   154 in
    95   fun clauseWeight (parm : parameters) models dist cl =
   155   fun clauseWeight (parm : parameters) mods dist mcl cl =
    96       let
   156       let
    97 (*TRACE3
   157 (*MetisTrace3
    98         val () = Parser.ppTrace Clause.pp "Waiting.clauseWeight: cl" cl
   158         val () = Print.trace Clause.pp "Waiting.clauseWeight: cl" cl
    99 *)
   159 *)
   100         val {symbolsWeight,literalsWeight,modelsWeight,modelChecks,...} = parm
   160         val {symbolsWeight,variablesWeight,literalsWeight,models,...} = parm
   101         val lits = Clause.literals cl
   161         val lits = Clause.literals cl
   102         val symbolsW = Math.pow (clauseSymbols lits, symbolsWeight)
   162         val symbolsW = Math.pow (clauseSymbols lits, symbolsWeight)
       
   163         val variablesW = Math.pow (clauseVariables lits, variablesWeight)
   103         val literalsW = Math.pow (clauseLiterals lits, literalsWeight)
   164         val literalsW = Math.pow (clauseLiterals lits, literalsWeight)
   104         val modelsW = Math.pow (clauseSat modelChecks models lits, modelsWeight)
   165         val modelsW = checkModels models mods mcl
   105 (*TRACE4
   166 (*MetisTrace4
   106         val () = trace ("Waiting.clauseWeight: dist = " ^
   167         val () = trace ("Waiting.clauseWeight: dist = " ^
   107                         Real.toString dist ^ "\n")
   168                         Real.toString dist ^ "\n")
   108         val () = trace ("Waiting.clauseWeight: symbolsW = " ^
   169         val () = trace ("Waiting.clauseWeight: symbolsW = " ^
   109                         Real.toString symbolsW ^ "\n")
   170                         Real.toString symbolsW ^ "\n")
       
   171         val () = trace ("Waiting.clauseWeight: variablesW = " ^
       
   172                         Real.toString variablesW ^ "\n")
   110         val () = trace ("Waiting.clauseWeight: literalsW = " ^
   173         val () = trace ("Waiting.clauseWeight: literalsW = " ^
   111                         Real.toString literalsW ^ "\n")
   174                         Real.toString literalsW ^ "\n")
   112         val () = trace ("Waiting.clauseWeight: modelsW = " ^
   175         val () = trace ("Waiting.clauseWeight: modelsW = " ^
   113                         Real.toString modelsW ^ "\n")
   176                         Real.toString modelsW ^ "\n")
   114 *)
   177 *)
   115         val weight = dist * symbolsW * literalsW * modelsW + priority cl
   178         val weight = dist * symbolsW * variablesW * literalsW * modelsW
   116 (*TRACE3
   179         val weight = weight + clausePriority cl
       
   180 (*MetisTrace3
   117         val () = trace ("Waiting.clauseWeight: weight = " ^
   181         val () = trace ("Waiting.clauseWeight: weight = " ^
   118                         Real.toString weight ^ "\n")
   182                         Real.toString weight ^ "\n")
   119 *)
   183 *)
   120       in
   184       in
   121         weight
   185         weight
   124 
   188 
   125 (* ------------------------------------------------------------------------- *)
   189 (* ------------------------------------------------------------------------- *)
   126 (* Adding new clauses.                                                       *)
   190 (* Adding new clauses.                                                       *)
   127 (* ------------------------------------------------------------------------- *)
   191 (* ------------------------------------------------------------------------- *)
   128 
   192 
       
   193 fun add' waiting dist mcls cls =
       
   194     let
       
   195       val Waiting {parameters,clauses,models} = waiting
       
   196       val {models = modelParameters, ...} = parameters
       
   197 
       
   198       val dist = dist + Math.ln (Real.fromInt (length cls))
       
   199 
       
   200       fun addCl ((mcl,cl),acc) =
       
   201           let
       
   202             val weight = clauseWeight parameters models dist mcl cl
       
   203           in
       
   204             Heap.add acc (weight,(dist,cl))
       
   205           end
       
   206 
       
   207       val clauses = List.foldl addCl clauses (zip mcls cls)
       
   208 
       
   209       val () = perturbModels modelParameters models mcls
       
   210     in
       
   211       Waiting {parameters = parameters, clauses = clauses, models = models}
       
   212     end;
       
   213 
   129 fun add waiting (_,[]) = waiting
   214 fun add waiting (_,[]) = waiting
   130   | add waiting (dist,cls) =
   215   | add waiting (dist,cls) =
   131     let
   216     let
   132 (*TRACE3
   217 (*MetisTrace3
   133       val () = Parser.ppTrace pp "Waiting.add: waiting" waiting
   218       val () = Print.trace pp "Waiting.add: waiting" waiting
   134       val () = Parser.ppTrace (Parser.ppList Clause.pp) "Waiting.add: cls" cls
   219       val () = Print.trace (Print.ppList Clause.pp) "Waiting.add: cls" cls
   135 *)
   220 *)
   136 
   221 
   137       val Waiting {parameters,clauses,models} = waiting
   222       val waiting = add' waiting dist (mkModelClauses cls) cls
   138 
   223 
   139       val dist = dist + Math.ln (Real.fromInt (length cls))
   224 (*MetisTrace3
   140 
   225       val () = Print.trace pp "Waiting.add: waiting" waiting
   141       val weight = clauseWeight parameters models dist
       
   142 
       
   143       fun f (cl,acc) = Heap.add acc (weight cl, (dist,cl))
       
   144 
       
   145       val clauses = foldl f clauses cls
       
   146 
       
   147       val waiting =
       
   148           Waiting {parameters = parameters, clauses = clauses, models = models}
       
   149 
       
   150 (*TRACE3
       
   151       val () = Parser.ppTrace pp "Waiting.add: waiting" waiting
       
   152 *)
   226 *)
   153     in
   227     in
   154       waiting
   228       waiting
   155     end;
   229     end;
   156 
   230 
   157 local
   231 local
   158   fun cmp ((w1,_),(w2,_)) = Real.compare (w1,w2);
   232   fun cmp ((w1,_),(w2,_)) = Real.compare (w1,w2);
   159 
   233 
   160   fun empty parameters =
   234   fun empty parameters axioms conjecture =
   161       let
   235       let
       
   236         val {models = modelParameters, ...} = parameters
   162         val clauses = Heap.new cmp
   237         val clauses = Heap.new cmp
   163         and models = map Model.new (#models parameters)
   238         and models = map (initialModel axioms conjecture) modelParameters
   164       in
   239       in
   165         Waiting {parameters = parameters, clauses = clauses, models = models}
   240         Waiting {parameters = parameters, clauses = clauses, models = models}
   166       end;
   241       end;
   167 in
   242 in
   168   fun new parameters cls = add (empty parameters) (0.0,cls);
   243   fun new parameters {axioms,conjecture} =
       
   244       let
       
   245         val mAxioms = mkModelClauses axioms
       
   246         and mConjecture = mkModelClauses conjecture
       
   247 
       
   248         val waiting = empty parameters mAxioms mConjecture
       
   249       in
       
   250         add' waiting 0.0 (mAxioms @ mConjecture) (axioms @ conjecture)
       
   251       end;
   169 end;
   252 end;
   170 
   253 
   171 (* ------------------------------------------------------------------------- *)
   254 (* ------------------------------------------------------------------------- *)
   172 (* Removing the lightest clause.                                             *)
   255 (* Removing the lightest clause.                                             *)
   173 (* ------------------------------------------------------------------------- *)
   256 (* ------------------------------------------------------------------------- *)