1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.sat4j.csp;
20
21 import java.io.FileNotFoundException;
22 import java.io.IOException;
23 import java.io.InputStreamReader;
24 import java.net.URL;
25 import java.util.HashMap;
26 import java.util.Map;
27
28 import org.mozilla.javascript.Context;
29 import org.mozilla.javascript.ContextFactory;
30 import org.mozilla.javascript.Script;
31 import org.mozilla.javascript.Scriptable;
32 import org.sat4j.core.Vec;
33 import org.sat4j.csp.encodings.BinarySupportEncoding;
34 import org.sat4j.csp.encodings.DirectEncoding;
35 import org.sat4j.specs.ContradictionException;
36 import org.sat4j.specs.ISolver;
37 import org.sat4j.specs.IVec;
38
39
40
41
42
43
44 public class Predicate implements Clausifiable {
45
46 private String expr;
47
48 private Encoding encoding;
49
50 private final IVec<String> variables = new Vec<String>();
51
52 private static Context cx;
53
54 private static Scriptable scope;
55
56 static {
57 cx = Context.enter();
58
59 scope = cx.initStandardObjects();
60
61
62 try {
63 URL url = Predicate.class.getResource("predefinedfunctions.js");
64 cx.evaluateReader(scope, new InputStreamReader(url.openStream()),
65 "predefinedfunctions.js", 1, null);
66
67 } catch (FileNotFoundException e) {
68
69 e.printStackTrace();
70 } catch (IOException e) {
71
72 e.printStackTrace();
73 }
74 }
75
76 public Predicate() {
77 }
78
79 public void setExpression(String expr) {
80 this.expr = expr.replaceAll("if\\(", "ite(");
81 }
82
83 public void addVariable(String name) {
84 variables.push(name);
85 }
86
87 private boolean evaluate(int[] values) {
88 assert values.length == variables.size();
89 for (int i = 0; i < variables.size(); i++) {
90 scope.put(variables.get(i), scope, values[i]);
91 }
92 Object result = myscript.exec(cx, scope);
93 return Context.toBoolean(result);
94 }
95
96 public void toClause(ISolver solver, IVec<Var> vscope, IVec<Evaluable> vars)
97 throws ContradictionException {
98 if (myscript == null) {
99 myscript = cx.compileString(expr, "rhino.log", 1, null);
100 }
101 if (vscope.size() == 2) {
102 encoding = BinarySupportEncoding.instance();
103 } else {
104 encoding = DirectEncoding.instance();
105 }
106 encoding.onInit(solver, vscope);
107 int[] tuple = new int[vars.size()];
108 valuemapping.clear();
109 find(tuple, 0, vscope, vars, solver);
110 encoding.onFinish(solver, vscope);
111 }
112
113 private final Map<Evaluable, Integer> valuemapping = new HashMap<Evaluable, Integer>();
114
115 private Script myscript;
116
117 private void find(int[] tuple, int n, IVec<Var> theScope,
118 IVec<Evaluable> vars, ISolver solver) throws ContradictionException {
119 if (valuemapping.size() == theScope.size()) {
120 for (int i = 0; i < tuple.length; i++) {
121 Evaluable ev = vars.get(i);
122 Integer value = valuemapping.get(ev);
123 if (value == null) {
124 tuple[i] = ev.domain().get(0);
125 } else {
126 tuple[i] = value;
127 }
128 }
129 if (evaluate(tuple)) {
130 encoding.onSupport(solver, theScope, valuemapping);
131 } else {
132 encoding.onNogood(solver, theScope, valuemapping);
133 }
134 } else {
135 Var var = theScope.get(n);
136 Domain domain = var.domain();
137 for (int i = 0; i < domain.size(); i++) {
138 valuemapping.put(var, domain.get(i));
139 find(tuple, n + 1, theScope, vars, solver);
140 }
141 valuemapping.remove(var);
142 }
143 }
144 }