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 (* ------------------------------------------------------------------------- *) |