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