/**
*
*/
package kodkod.examples.tptp;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import kodkod.ast.Expression;
import kodkod.ast.Formula;
import kodkod.ast.Relation;
import kodkod.ast.Variable;
import kodkod.engine.Solution;
import kodkod.engine.Solver;
import kodkod.engine.satlab.SATFactory;
import kodkod.instance.Bounds;
import kodkod.instance.Instance;
import kodkod.instance.Tuple;
import kodkod.instance.TupleFactory;
import kodkod.instance.TupleSet;
import kodkod.instance.Universe;
/**
* @author emina
*
*/
public final class ALG195_1 {
final Relation[] e1, e2, h;
final Relation op1, op2, s1, s2;
/**
* Constructs a new instance of Quasigroups7.
*/
ALG195_1() {
op1 = Relation.ternary("op1");
op2 = Relation.ternary("op2");
s1 = Relation.unary("s1");
s2 = Relation.unary("s2");
e1 = new Relation[7];
e2 = new Relation[7];
h = new Relation[7];
for(int i = 0; i < 7; i++) {
e1[i] = Relation.unary("e1"+i);
e2[i] = Relation.unary("e2"+i);
h[i] = Relation.binary("h"+(i+1));
}
}
private static Formula function(Relation s, Relation op) {
final Variable x = Variable.unary("x"), y = Variable.unary("y");
return y.join(x.join(op)).one().forAll(x.oneOf(s).and(y.oneOf(s)));
}
/**
* Returns the relation constraints.
* @returns the relation constraints.
*/
public final Formula decls() {
Formula f = function(s1, op1).and(function(s2, op2));
for(Relation x: h) {
f = f.and(x.function(s1, s2));
}
for(int i = 0; i < 7; i++) {
f = f.and(h[i].function(s1, s2));
f = f.and(e1[i].one()).and(e2[i].one());
}
return f;
}
/**
* States that op is a latin square over s = e[0] +...+ e[6].
* @requires e's are unary, s is unary, op is ternary
*/
private static Formula opCoversRange(Relation[] e, Relation s, Relation op) {
Formula f = Formula.TRUE;
for( Relation x : e) {
f = f.and(s.eq(s.join(x.join(op)))).and(s.eq(x.join(s.join(op))));
}
return f;
}
/**
* Returns axioms 2 and 7.
* @return ax2 and ax7
*/
public final Formula ax2ax7() {
return opCoversRange(e1, s1, op1);
}
/**
* Parametrization of axioms 3 and 6.
* @requires s is unary, op is ternary
*/
private static Formula ax3and6(Relation[] e, Relation op) {
Formula f = Formula.TRUE;
for( Relation x : e) {
for (Relation y: e) {
Expression expr0 = x.join(y.join(op)); // op(y,x)
Expression expr1 = y.join(expr0.join(op)); // op(op(y,x),y)
Expression expr2 = y.join(expr1.join(op)); // op(op(op(y,x),y),y)
f = f.and(expr2.eq(x));
}
}
return f;
}
/**
* Returns axiom 3.
* @return ax3
*/
public final Formula ax3() {
return ax3and6(e1,op1);
}
/**
* Returns axioms 5 and 8.
* @return ax5 and ax8
*/
public final Formula ax5ax8() {
return opCoversRange(e2, s2, op2);
}
/**
* Returns axiom 6.
* @return ax6
*/
public final Formula ax6() {
return ax3and6(e2,op2);
}
/**
* Parametrization of axioms 12 and 13.
* @requires e's are unary, op is ternary
*/
Formula ax12and13(Relation[] e, Relation op) {
Formula f = Formula.TRUE;
for(Relation r : e) {
f = f.and(r.join(r.join(op)).eq(r).not());
}
return f;
}
/**
* Returns axioms 9 and 10.
* @return axioms 9 and 10.
*/
// public final Formula ax9ax10() {
// Formula f = Formula.TRUE;
// for(int i = 0 ; i < 6; i++) {
// for(int j = i+1; j < 7; j++) {
// f = f.and(e1[i].eq(e1[j]).not());
// f = f.and(e2[i].eq(e2[j]).not());
// }
// }
// return f;
// }
/**
* Returns axiom 12.
* @return ax12
*/
public final Formula ax12() {
return ax12and13(e1, op1);
}
/**
* Returns axiom 13.
* @return ax13
*/
public final Formula ax13() {
return ax12and13(e2, op2);
}
/**
* Parametrization of axioms 14 and 15.
* @requires e's are unary, op is ternary
*/
Formula ax14and15(Relation[] e, Relation op) {
final Expression expr0 = e[5].join(op); // op(e5,...)
final Expression expr1 = e[5].join(expr0); // op(e5,e5)
final Expression expr2 = expr1.join(expr0); // op(e5,op(e5,e5))
final Expression expr3 = expr2.join(expr2.join(op)); // op(op(e5,op(e5,e5)),op(e5,op(e5,e5)))
final Expression expr3a = expr3.join(op); // op(op(op(e5,op(e5,e5)),op(e5,op(e5,e5))),...)
final Expression expr4 = e[5].join(expr3a); // op(op(op(e5,op(e5,e5)),op(e5,op(e5,e5))),e5)
// e0 = op(op(op(e5,op(e5,e5)),op(e5,op(e5,e5))),op(e5,op(e5,e5)))
final Formula f0 = e[0].eq(expr2.join(expr3a));
// e1 = op(e5,e5)
final Formula f1 = e[1].eq(expr1);
// e2 = op(op(e5,op(e5,e5)),op(e5,op(e5,e5)))
final Formula f2 = e[2].eq(expr3);
// e3 = op(op(op(e5,op(e5,e5)),op(e5,op(e5,e5))),e5)
final Formula f3 = e[3].eq(expr4);
// e4 = op(e5,op(e5,e5))
final Formula f4 = e[4].eq(expr2);
// e6 = op(op(op(op(e5,op(e5,e5)),op(e5,op(e5,e5))),e5),op(e5,op(e5,e5)))
final Formula f6 = e[6].eq(expr2.join(expr4.join(op)));
return f0.and(f1).and(f2).and(f3).and(f4).and(f6);
}
/**
* Returns lines 1 and 3-6 of axiom 14.
* @return ax14
*/
public final Formula ax14() {
return ax14and15(e1, op1);
}
/**
* Returns lines 1 and 3-6 of axiom 15.
* @return ax15
*/
public final Formula ax15() {
return ax14and15(e2, op2);
}
/**
* Parametrization of axioms 16-22.
* @requires e is unary, h is binary
*/
Formula ax16_22(Relation e, Relation h) {
final Expression expr0 = e.join(op2); // op2(e,...)
final Expression expr1 = e.join(expr0); // op2(e,e)
final Expression expr2 = expr1.join(expr0); // op2(e,op2(e,e))
final Expression expr3 = expr2.join(expr2.join(op2)); // op2(op2(e,op2(e,e)),op2(e,op2(e,e)))
final Expression expr3a = expr3.join(op2); // op2(op2(op2(e,op2(e,e)),op2(e,op2(e,e))),...)
final Expression expr4 = e.join(expr3a); // op2(op2(op2(e,op2(e,e)),op2(e,op2(e,e))),e)
// h(e10) = op2(op2(op2(e,op2(e,e)),op2(e,op2(e,e))),op2(e,op2(e,e)))
final Formula f0 = e1[0].join(h).eq(expr2.join(expr3a));
// h(e11) = op2(e,e)
final Formula f1 = e1[1].join(h).eq(expr1);
// h(e12) = op2(op2(e,op2(e,e)),op2(e,op2(e,e)))
final Formula f2 = e1[2].join(h).eq(expr3);
// h(e13) = op2(op2(op2(e,op2(e,e)),op2(e,op2(e,e))),e)
final Formula f3 = e1[3].join(h).eq(expr4);
// h(e14) = op2(e,op2(e,e))
final Formula f4 = e1[4].join(h).eq(expr2);
// h1(e15) = e
final Formula f5 = e1[5].join(h).eq(e);
// h(e16) = op2(op2(op2(op2(e,op2(e,e)),op2(e,op2(e,e))),e),op2(e,op2(e,e)))
final Formula f6 = e1[6].join(h).eq(expr2.join(expr4.join(op2)));
return f0.and(f1).and(f2).and(f3).and(f4).and(f5).and(f6);
}
/**
* Returns axioms 16-22.
* @return axioms 16-22.
*/
public final Formula ax16_22() {
Formula f = Formula.TRUE;
for(int i = 0; i < 7; i++) {
f = f.and(ax16_22(e2[i], h[i]));
}
return f;
}
/**
* Returns the conjunction of all axioms and implicit constraints (decls()).
* @return the conjunction of all axioms and implicit constraints
*/
public final Formula axioms() {
return decls().and(ax2ax7()).and(ax3()).and(ax5ax8()).and(ax6()).
and(ax12()).and(ax13()).and(ax14()).and(ax15()).and(ax16_22());
}
/**
* Returns the part of the conjecture 1 that applies to the given h.
* @return the part of the conjecture 1 that applies to the given h.
*/
private final Formula co1h(Relation h) {
Formula f = Formula.TRUE;
for(Relation x : e1) {
for(Relation y: e1) {
Expression expr0 = (y.join(x.join(op1))).join(h); // h(op1(x,y))
Expression expr1 = (y.join(h)).join((x.join(h)).join(op2)); // op2(h(x),h(y))
f = f.and(expr0.eq(expr1));
}
}
return f.and(s2.eq(s1.join(h)));
}
/**
* Returns conjecture 1.
* @return co1
*/
public final Formula co1() {
Formula f = Formula.FALSE;
for(int i = 0; i < 7; i++) {
f = f.or(co1h(h[i]));
}
return f;
}
/**
* Returns the partial bounds the problem (axioms 1, 4, 9-11).
* @return the partial bounds for the problem
*/
public Bounds bounds() {
final List<String> atoms = new ArrayList<String>(14);
for(int i = 0; i < 7; i++)
atoms.add("e1"+i);
for(int i = 0; i < 7; i++)
atoms.add("e2"+i);
final Universe u = new Universe(atoms);
final Bounds b = new Bounds(u);
final TupleFactory f = u.factory();
final TupleSet s1bound = f.range(f.tuple("e10"), f.tuple("e16"));
final TupleSet s2bound = f.range(f.tuple("e20"), f.tuple("e26"));
b.boundExactly(s1, s1bound);
b.boundExactly(s2, s2bound);
// axioms 9, 10, 11
for(int i = 0; i < 7; i++) {
b.boundExactly(e1[i], f.setOf("e1"+i));
b.boundExactly(e2[i], f.setOf("e2"+i));
}
// axom 1
b.bound(op1, f.area(f.tuple("e10", "e10", "e10"), f.tuple("e16", "e16", "e16")));
// axiom 4
b.bound(op2, f.area(f.tuple("e20", "e20", "e20"), f.tuple("e26", "e26", "e26")));
final TupleSet hbound = s1bound.product(s2bound);
for(Relation r : h) {
b.bound(r, hbound);
}
return b;
}
private static void displayOp(Instance instance, Relation op) {
System.out.println("\n"+op+":");
final Iterator<Tuple> iter = instance.tuples(op).iterator();
for(int i = 0; i < 7; i++) {
for(int j = 0; j < 7; j++) {
System.out.print(iter.next().atom(2));
System.out.print("\t");
}
System.out.println();
}
}
/**
* Prints the values of the op1, op2, and h1-h7 relations
* to standard out.
*/
void display(Instance instance) {
displayOp(instance, op1);
displayOp(instance, op2);
for(int i = 0; i < 7; i++) {
System.out.println("\n"+h[i]+":");
System.out.println(instance.tuples(h[i]));
}
}
private static void usage() {
System.out.println("java examples.tptp.ALG195_1");
System.exit(1);
}
/**
* Usage: java examples.tptp.ALG195_1
*/
public static void main(String[] args) {
try {
final ALG195_1 model = new ALG195_1();
final Solver solver = new Solver();
solver.options().setSolver(SATFactory.MiniSat);
final Formula f = model.axioms().and(model.co1().not());
final Bounds b = model.bounds();
// System.out.println(model.decls());
// System.out.println(model.ax2ax7());
// System.out.println(b);
final Solution sol = solver.solve(f, b);
if (sol.instance()==null) {
System.out.println(sol);
} else {
System.out.println(sol.stats());
model.display(sol.instance());
}
} catch (NumberFormatException nfe) {
usage();
}
}
}