/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2010.
*/
package x10.constraints.tests;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import junit.framework.TestCase;
import x10.constraint.XConstraint;
import x10.constraint.XConstraintManager;
import x10.constraint.XEquals;
import x10.constraint.XFailure;
import x10.constraint.XTerm;
import x10.constraint.XVar;
public class FormulaTest extends TestCase {
public FormulaTest() {
super("FormulaTest");
}
HashMap<String, XVar> vars = new HashMap<String, XVar>();
XVar makeUQV(String id) {
XVar v = vars.get(id);
if (v !=null) return v;
v = XConstraintManager.getConstraintSystem().makeUQV(id);
vars.put(id, v);
return v;
}
public XConstraint parse(String s) {
char[] buf = s.toCharArray();
int i = 0;
while (Character.isWhitespace(buf[i])) {
i++;
}
if (buf[i] == '(') {
i++;
}
else {
assert false : "cannot parse " + s;
}
XConstraint c = XConstraintManager.getConstraintSystem().makeConstraint();
Pair<Integer,XTerm> p = parse(buf, i);
XTerm t = p.snd;
if (t != null) {
try {
if (t instanceof XEquals) {
c.addBinding(((XEquals) t).left(), ((XEquals) t).right());
}
else {
c.addTerm(t);
}
}
catch (XFailure e) {
}
}
return c;
}
public Pair<Integer,String> parseId(char[] buf, int i) {
int n = buf.length;
char c = buf[i];
int begin = i;
for (; i < n; i++) {
c = buf[i];
if (! Character.isLetter(c)) {
break;
}
}
String id = new String(buf, begin, i-begin);
return new Pair<Integer, String>(i, id);
}
public Pair<Integer,XTerm> parse(char[] buf, int i) {
int n = buf.length;
if (i >= n) {
return new Pair<Integer,XTerm>(n, null);
}
char c = buf[i];
while (Character.isWhitespace(c)) {
i++;
c = buf[i];
}
String op = null;
if (Character.isLetter(c)) {
Pair<Integer,String> p = parseId(buf, i);
i = p.fst;
c = buf[i];
op = p.snd;
}
else if (c == '=') {
i++;
c = buf[i];
if (c == '=') {
i++;
c = buf[i];
op = "==";
}
}
else if (c == '!') {
i++;
c = buf[i];
op = "!";
}
else if (c == '&') {
i++;
c = buf[i];
if (c == '&') {
i++;
c = buf[i];
op = "&&";
}
}
if (op == null) {
assert false : "bad op";
return null;
}
List<XTerm> terms = new ArrayList<XTerm>();
while (true) {
XTerm t = null;
while (Character.isWhitespace(c)) {
i++;
c = buf[i];
}
if (c == '(') {
Pair<Integer,XTerm> p = parse(buf, i+1);
t = p.snd;
i = p.fst;
c = buf[i];
}
XVar left = null;
while (Character.isLetter(c)) {
Pair<Integer,String> p = parseId(buf, i);
i = p.fst;
c = buf[i];
String id = p.snd;
if (left != null) {
left = XConstraintManager.getConstraintSystem().makeField(left, id);
}
else {
left = makeUQV(id);
}
if (c == '.') {
i++;
c = buf[i];
}
else {
break;
}
}
if (left != null) {
t = left;
}
if (t != null) {
terms.add(t);
}
if (c == ')') {
i++;
break;
}
}
if (op.toString().equals("==")) {
XTerm left = terms.get(0);
for (int k = 1; k < terms.size(); k++) {
left = XConstraintManager.getConstraintSystem().makeEquals(left, terms.get(k));
}
return new Pair<Integer,XTerm>(i, left);
}
if (op.toString().equals("&&")) {
XTerm left = terms.get(0);
for (int k = 1; k < terms.size(); k++) {
left = XConstraintManager.getConstraintSystem().makeAnd(left, terms.get(k));
}
return new Pair<Integer,XTerm>(i, left);
}
if (op.toString().equals("!")) {
return new Pair<Integer,XTerm>(i, XConstraintManager.getConstraintSystem().makeNot(terms.get(0)));
}
return new Pair<Integer,XTerm>(i, XConstraintManager.getConstraintSystem().makeAtom(op, terms.toArray(new XTerm[0])));
}
XConstraint c1 = parse("(== x y)");
XConstraint c2 = parse("(== y x)");
XConstraint c3 = parse("(== y x)");
XConstraint c4 = parse("(&& (== y x) (== x.f z))");
XConstraint c5 = parse("(== y.f z)");
XConstraint c6 = parse("(&& (F x.f z) (== x.f z) (== y x))");
XConstraint c7 = parse("(F y.f z)");
XConstraint c8 = parse("(F z x.f)");
XConstraint c9 = parse("(! (! (== x y)))");
public void test1() throws Throwable {
assertTrue(c1.entails(c2));
}
public void test2() throws Throwable {
assertTrue(c2.entails(c1));
}
public void test3() throws Throwable {
assertTrue(c3.entails(c1));
}
public void test4() throws Throwable {
assertTrue(c4.entails(c5));
}
public void test5() throws Throwable {
assertFalse(c5.entails(c4));
}
public void test6() throws Throwable {
assertTrue(c6.entails(c7));
}
public void test7() throws Throwable {
assertTrue(c6.entails(c8));
}
public void test8() throws Throwable {
assertFalse(c8.entails(c6));
}
public void test9() throws Throwable {
assertTrue(c9.entails(c9));
}
public void test10() throws Throwable {
assertTrue(c1.entails(c9));
}
}