kodkod.ast.operator.FormulaOperator Java Examples

The following examples show how to use kodkod.ast.operator.FormulaOperator. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: TranslatorTest.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
private final void testNary(FormulaOperator op) {
    bounds.bound(r1[0], factory.range(factory.tuple(1, 0), factory.tuple(1, 3)));
    bounds.bound(r1[1], factory.range(factory.tuple(1, 2), factory.tuple(1, 5)));
    bounds.bound(r1[3], factory.range(factory.tuple(1, 3), factory.tuple(1, 6)));

    for (int i = 2; i <= 5; i++) {
        final Formula[] exprs = new Formula[i];
        exprs[0] = r1[0].some();
        Formula binExpr = r1[0].some();
        for (int j = 1; j < i; j++) {
            binExpr = binExpr.compose(op, r1[j % 4].some());
            exprs[j] = r1[j % 4].some();
        }
        Formula nExpr = Formula.compose(op, exprs);
        final Solution sol = solver.solve(binExpr.iff(nExpr).not(), bounds);
        assertNull(sol.instance());
    }

}
 
Example #2
Source File: FOL2BoolTranslator.java    From kodkod with MIT License 6 votes vote down vote up
/** 
 * Calls lookup(formula) and returns the cached value, if any.  
 * If a translation has not been cached, translates the formula,
 * calls cache(...) on it and returns it.
 * @return let t = lookup(formula) | some t => t, 
 * 	cache(formula, formula.op(formula.left.accept(this), formula.right.accept(this))
 */
public final BooleanValue visit(NaryFormula formula) {
	final BooleanValue ret = lookup(formula);
	if (ret!=null) return ret;

	final FormulaOperator op = formula.op();		
	final Operator.Nary boolOp;
	
	switch(op) { 
	case AND : boolOp = Operator.AND; break;
	case OR  : boolOp = Operator.OR;  break;
	default	 : throw new IllegalArgumentException("Unknown nary operator: " + op);
	}
	
	final BooleanAccumulator acc = BooleanAccumulator.treeGate(boolOp);
	final BooleanValue shortCircuit = boolOp.shortCircuit();
	for(Formula child : formula) { 
		if (acc.add(child.accept(this))==shortCircuit)
			break;
	}
	
	return cache(formula, interpreter.factory().accumulate(acc));
}
 
Example #3
Source File: Proc.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
@Override
public Proc compose(FormulaOperator op, Proc right) {
    switch (op) {
        case AND :
            if (right instanceof FOL) {
                return composeFormula(right.bounds, op, ((FOL) right).formula);
            }
            if (right instanceof OR) {
                return new OR(composeAll(op, this, ((OR) right).disjuncts));
            }
            if (right instanceof AND) {
                return make(superset(right), conjuncts.and(((AND) right).conjuncts), concat(quantProcs, ((AND) right).quantProcs));
            }
            throw new NotComposableException(op, this, right);
        case OR :
            return new OR(this, right);
        default :
            throw new IllegalStateException("Expected formula in NNF; got operator: " + op);
    }
}
 
Example #4
Source File: FOL2BoolTranslator.java    From kodkod with MIT License 6 votes vote down vote up
/** 
 * Calls lookup(binFormula) and returns the cached value, if any.  
 * If a translation has not been cached, translates the formula,
 * calls cache(...) on it and returns it.
 * @return let t = lookup(binFormula) | some t => t, 
 * 	cache(binFormula, binFormula.op(binFormula.left.accept(this), binFormula.right.accept(this))
 */
public final BooleanValue visit(BinaryFormula binFormula) {
	BooleanValue ret = lookup(binFormula);
	if (ret!=null) return ret;

	final BooleanValue left = binFormula.left().accept(this);
	final BooleanValue right = binFormula.right().accept(this);
	final FormulaOperator op = binFormula.op();
	final BooleanFactory f = interpreter.factory();

	switch(op) {
	case AND		: ret = f.and(left, right); break;
	case OR			: ret = f.or(left, right); break;
	case IMPLIES	: ret = f.implies(left, right); break;
	case IFF		: ret = f.iff(left, right); break;
	default : 
		throw new IllegalArgumentException("Unknown operator: " + op);
	}
	return cache(binFormula, ret);
}
 
Example #5
Source File: FormulaFlattener.java    From kodkod with MIT License 6 votes vote down vote up
/**
 * Visits the formula's children with appropriate settings
 * for the negated flag if bf  has not been visited before.
 * @see kodkod.ast.visitor.AbstractVoidVisitor#visit(kodkod.ast.BinaryFormula)
 */
public final void visit(BinaryFormula bf) { 
	if (visited(bf)) return;
	final FormulaOperator op = bf.op();
	if (op==IFF || (negated && op==AND) || (!negated && (op==OR || op==IMPLIES))) { // can't break down further in these cases
		addConjunct(bf);
	} else { // will break down further
		if (negated && op==IMPLIES) { // !(a => b) = !(!a || b) = a && !b
			negated = !negated;
			bf.left().accept(this);
			negated = !negated;
			bf.right().accept(this);
		} else {
			bf.left().accept(this);
			bf.right().accept(this);
		}
	}
}
 
Example #6
Source File: Skolemizer.java    From kodkod with MIT License 6 votes vote down vote up
/**
 * If not cached, visits the formula's children with appropriate settings
 * for the negated flag and the skolemDepth parameter.
 * @see kodkod.ast.visitor.AbstractReplacer#visit(kodkod.ast.BinaryFormula)
 */
public final Formula visit(BinaryFormula bf) {
	Formula ret = lookup(bf);
	if (ret!=null) return ret;			
	final FormulaOperator op = bf.op();
	final int oldDepth = skolemDepth;
	if (op==IFF || (negated && op==AND) || (!negated && (op==OR || op==IMPLIES))) { // cannot skolemize in these cases
		skolemDepth = -1;
	}
	final Formula left, right;
	if (negated && op==IMPLIES) { // !(a => b) = !(!a || b) = a && !b
		negated = !negated;
		left = bf.left().accept(this);
		negated = !negated;
		right = bf.right().accept(this);
	} else {
		left = bf.left().accept(this);
		right = bf.right().accept(this);
	}
	skolemDepth = oldDepth;
	ret = (left==bf.left()&&right==bf.right()) ? bf : left.compose(op, right);
	return source(cache(bf,ret),bf);
}
 
Example #7
Source File: Formula.java    From kodkod with MIT License 6 votes vote down vote up
/**
 * Returns the composition of the given formulas using the given operator. 
 * @requires formulas.size() != 2 => op.nary()
 * @return 
 * <pre> 
 *  formulas.size() = 0 => constant(op=AND) else
 *  formulas.size() = 1 => formulas.iterator().next() else 
 *  {e: Formula | e.children = formulas.toArray() and e.op = this }
 * </pre>
 */
public static Formula compose(FormulaOperator op, Collection<? extends Formula> formulas) { 
	switch(formulas.size()) { 
	case 0 : 	
		switch(op) { 
		case AND : return TRUE;
		case OR : return FALSE;
		default : throw new IllegalArgumentException("Expected at least one argument: " + formulas);
		}
	case 1 : 	return formulas.iterator().next();
	case 2 :
		final Iterator<? extends Formula> itr = formulas.iterator();
		return new BinaryFormula(itr.next(), op, itr.next());
	default : 			
		return new NaryFormula(op, formulas.toArray(new Formula[formulas.size()]));
	}
}
 
Example #8
Source File: PrettyPrinter.java    From kodkod with MIT License 6 votes vote down vote up
/** @ensures appends the tokenization of the given node to this.tokens */
public void visit(NaryFormula node) {
	final FormulaOperator op = node.op();
	boolean parens = parenthesize(op, node.child(0));
	if (parens) indent++;
	visitChild(node.child(0), parens);
	if (parens) indent--;
	for(int i = 1, size = node.size(); i < size; i++) { 
		infix(op);
		newline();
		parens = parenthesize(op, node.child(i));
		if (parens) indent++;
		visitChild(node.child(i), parens);
		if (parens) indent--;
	}
}
 
Example #9
Source File: PrettyPrinter.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
/**
 * @ensures appends the tokenization of the given node to this.tokens
 */
@Override
public void visit(BinaryFormula node) {
    final FormulaOperator op = node.op();
    final boolean pleft = parenthesize(op, node.left());
    if (pleft)
        indent++;
    visitChild(node.left(), pleft);
    if (pleft)
        indent--;
    infix(op);
    newline();
    final boolean pright = parenthesize(op, node.right());
    if (pright)
        indent++;
    visitChild(node.right(), pright);
    if (pright)
        indent--;
}
 
Example #10
Source File: PrettyPrinter.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
/**
 * @ensures appends the tokenization of the given node to this.tokens
 */
@Override
public void visit(NaryFormula node) {
    final FormulaOperator op = node.op();
    boolean parens = parenthesize(op, node.child(0));
    if (parens)
        indent++;
    visitChild(node.child(0), parens);
    if (parens)
        indent--;
    for (int i = 1, size = node.size(); i < size; i++) {
        infix(op);
        newline();
        parens = parenthesize(op, node.child(i));
        if (parens)
            indent++;
        visitChild(node.child(i), parens);
        if (parens)
            indent--;
    }
}
 
Example #11
Source File: FormulaFlattener.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
/**
 * Visits the formula's children with appropriate settings for the negated flag
 * if bf has not been visited before.
 *
 * @see kodkod.ast.visitor.AbstractVoidVisitor#visit(kodkod.ast.NaryFormula)
 */
@Override
public final void visit(NaryFormula nf) {
    if (visited(nf))
        return;
    final FormulaOperator op = nf.op();
    if ((negated && op == AND) || (!negated && op == OR)) { // can't break
                                                           // down further
                                                           // in these
                                                           // cases
        addConjunct(nf);
    } else { // will break down further
        for (Formula f : nf) {
            f.accept(this);
        }
    }
}
 
Example #12
Source File: FormulaFlattener.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
/**
 * Visits the formula's children with appropriate settings for the negated flag
 * if bf has not been visited before.
 *
 * @see kodkod.ast.visitor.AbstractVoidVisitor#visit(kodkod.ast.BinaryFormula)
 */
@Override
public final void visit(BinaryFormula bf) {
    if (visited(bf))
        return;
    final FormulaOperator op = bf.op();
    if (op == IFF || (negated && op == AND) || (!negated && (op == OR || op == IMPLIES))) { // can't
                                                                                           // break
                                                                                           // down
                                                                                           // further
                                                                                           // in
                                                                                           // these
                                                                                           // cases
        addConjunct(bf);
    } else { // will break down further
        if (negated && op == IMPLIES) { // !(a => b) = !(!a || b) = a && !b
            negated = !negated;
            bf.left().accept(this);
            negated = !negated;
            bf.right().accept(this);
        } else {
            bf.left().accept(this);
            bf.right().accept(this);
        }
    }
}
 
Example #13
Source File: TranslatorTest.java    From kodkod with MIT License 6 votes vote down vote up
private final void testNary(FormulaOperator op) { 
	bounds.bound(r1[0], factory.range(factory.tuple(1, 0), factory.tuple(1, 3)));
	bounds.bound(r1[1], factory.range(factory.tuple(1, 2), factory.tuple(1, 5)));
	bounds.bound(r1[3], factory.range(factory.tuple(1, 3), factory.tuple(1, 6)));
	
	for(int i = 2; i <= 5; i++) { 
		final Formula[] exprs = new Formula[i];
		exprs[0] = r1[0].some();
		Formula binExpr = r1[0].some();
		for(int j = 1; j < i; j++) { 
			binExpr = binExpr.compose(op, r1[j%4].some());
			exprs[j] = r1[j%4].some();
		}
		Formula nExpr = Formula.compose(op, exprs);
		final Solution sol = solver.solve(binExpr.iff(nExpr).not(), bounds);
		assertNull(sol.instance());	
	}
	
}
 
Example #14
Source File: A4Solution.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
/**
 * Associates the Kodkod formula to a particular Alloy Pos (if the Kodkod
 * formula is not already associated with an Alloy Expr or Alloy Pos)
 */
Formula k2pos(Formula formula, Pos pos) throws Err {
    if (solved)
        throw new ErrorFatal("Cannot alter the k->pos mapping since solve() has completed.");
    if (formula == null || pos == null || pos == Pos.UNKNOWN || k2pos.containsKey(formula))
        return formula;
    k2pos.put(formula, pos);
    if (formula instanceof BinaryFormula) {
        BinaryFormula b = (BinaryFormula) formula;
        if (b.op() == FormulaOperator.AND) {
            k2pos(b.left(), pos);
            k2pos(b.right(), pos);
        }
    }
    return formula;
}
 
Example #15
Source File: A4Solution.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
/**
 * Associates the Kodkod formula to a particular Alloy Expr (if the Kodkod
 * formula is not already associated with an Alloy Expr or Alloy Pos)
 */
Formula k2pos(Formula formula, Expr expr) throws Err {
    if (solved)
        throw new ErrorFatal("Cannot alter the k->pos mapping since solve() has completed.");
    if (formula == null || expr == null || k2pos.containsKey(formula))
        return formula;
    k2pos.put(formula, expr);
    if (formula instanceof BinaryFormula) {
        BinaryFormula b = (BinaryFormula) formula;
        if (b.op() == FormulaOperator.AND) {
            k2pos(b.left(), expr);
            k2pos(b.right(), expr);
        }
    }
    return formula;
}
 
Example #16
Source File: PrettyPrinter.java    From quetzal with Eclipse Public License 2.0 6 votes vote down vote up
/** @effects appends the tokenization of the given node to this.tokens */
public void visit(BinaryFormula node) {
	if (displayed(node)) return;
	final boolean oldTop = top;
	final FormulaOperator op = node.op();
	if (op==IFF || (negated && op==AND) || (!negated && (op==OR || op==IMPLIES))) { // not top in these cases
		top = false;
	}
	final boolean pleft = parenthesize(op, node.left());
	final boolean flip = (negated && op==IMPLIES);
	
	if (pleft) indent++;
	negated = negated ^ flip;
	visitChild(node.left(), pleft);
	if (pleft) indent--;
	infix(op);
	if (top) newline();
	final boolean pright =  parenthesize(op, node.right());
	if (pright) indent++;
	negated = negated ^ flip;
	visitChild(node.right(), pright);
	if (pright) indent--;
	top = oldTop;
}
 
Example #17
Source File: Formula.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the composition of the given formulas using the given operator.
 *
 * @requires formulas.size() != 2 => op.nary()
 * @return
 *
 *         <pre>
 *  formulas.size() = 0 => constant(op=AND) else
 *  formulas.size() = 1 => formulas.iterator().next() else
 *  {e: Formula | e.children = formulas.toArray() and e.op = this }
 *         </pre>
 */
public static Formula compose(FormulaOperator op, Collection< ? extends Formula> formulas) {
    switch (formulas.size()) {
        case 0 :
            switch (op) {
                case AND :
                    return TRUE;
                case OR :
                    return FALSE;
                default :
                    throw new IllegalArgumentException("Expected at least one argument: " + formulas);
            }
        case 1 :
            return formulas.iterator().next();
        case 2 :
            final Iterator< ? extends Formula> itr = formulas.iterator();
            return new BinaryFormula(itr.next(), op, itr.next());
        default :
            return new NaryFormula(op, formulas.toArray(new Formula[formulas.size()]));
    }
}
 
Example #18
Source File: Formula.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the composition of the given formulas using the given operator.
 *
 * @requires formulas.length != 2 => op.nary()
 * @return
 *
 *         <pre>
 *  formulas.length = 0 => constant(op=AND) else
 * 	formulas.length=1 => formulas[0] else
 *  {e: Formula | e.children = formulas and e.op = this }
 *         </pre>
 */
public static Formula compose(FormulaOperator op, Formula... formulas) {
    switch (formulas.length) {
        case 0 :
            switch (op) {
                case AND :
                    return TRUE;
                case OR :
                    return FALSE;
                default :
                    throw new IllegalArgumentException("Expected at least one argument: " + Arrays.toString(formulas));
            }
        case 1 :
            return formulas[0];
        case 2 :
            return new BinaryFormula(formulas[0], op, formulas[1]);
        default :
            return new NaryFormula(op, Containers.copy(formulas, new Formula[formulas.length]));
    }
}
 
Example #19
Source File: PrettyPrinter.java    From quetzal with Eclipse Public License 2.0 6 votes vote down vote up
/** @effects appends the tokenization of the given node to this.tokens */
public void visit(NaryFormula node) {
	if (displayed(node)) return;
	final boolean oldTop = top;
	final FormulaOperator op = node.op();
	if ((negated && op==AND) || (!negated && op==OR)) { // not top in these cases
		top = false;
	}
	boolean parens = parenthesize(op, node.child(0));
	negated = negated ^ (op==OR);
	if (parens) indent++;
	visitChild(node.child(0), parens);
	if (parens) indent--;
	for(int i = 1, size = node.size(); i < size; i++) { 
		infix(op);
		if (top) newline();
		parens = parenthesize(op, node.child(i));
		if (parens) indent++;
		visitChild(node.child(i), parens);
		if (parens) indent--;
	}
	negated = negated ^ (op==OR);
	top = oldTop;
}
 
Example #20
Source File: Nodes.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
public static List<Formula> allConjuncts(Formula formula, List<Formula> acc) {
    List<Formula> ans = acc != null ? acc : new ArrayList<Formula>();
    if (formula instanceof BinaryFormula) {
        final BinaryFormula bin = (BinaryFormula) formula;
        if (bin.op() == FormulaOperator.AND) {
            allConjuncts(bin.left(), ans);
            allConjuncts(bin.right(), ans);
            return ans;
        }
    }
    if (formula instanceof NaryFormula) {
        final NaryFormula nf = (NaryFormula) formula;
        if (nf.op() == FormulaOperator.AND) {
            for (Formula child : nf) {
                allConjuncts(child, ans);
            }
            return ans;
        }
    }
    ans.add(formula);
    return ans;
}
 
Example #21
Source File: AnnotatedNode.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
/**
 * Visits the children of the given formula if it has not been visited already
 * with the given value of the negated flag and if binFormula.op==IMPLIES &&
 * negated or binFormula.op==AND && !negated or binFormula.op==OR && negated.
 * Otherwise does nothing.
 *
 * @see kodkod.ast.visitor.AbstractVoidVisitor#visit(kodkod.ast.BinaryFormula)
 */
@Override
public void visit(BinaryFormula binFormula) {
    if (visited(binFormula))
        return;
    final FormulaOperator op = binFormula.op();

    if ((!negated && op == AND) || (negated && op == OR)) { // op==AND
                                                           // || op==OR
        binFormula.left().accept(this);
        binFormula.right().accept(this);
    } else if (negated && op == IMPLIES) { // !(a => b) = !(!a || b) = a
                                          // && !b
        negated = !negated;
        binFormula.left().accept(this);
        negated = !negated;
        binFormula.right().accept(this);
    }
}
 
Example #22
Source File: PrettyPrinter.java    From kodkod with MIT License 5 votes vote down vote up
/** @ensures appends the tokenization of the given node to this.tokens */
public void visit(BinaryFormula node) {
	final FormulaOperator op = node.op();
	final boolean pleft = parenthesize(op, node.left());
	if (pleft) indent++;
	visitChild(node.left(), pleft);
	if (pleft) indent--;
	infix(op);
	newline();
	final boolean pright =  parenthesize(op, node.right());
	if (pright) indent++;
	visitChild(node.right(), pright);
	if (pright) indent--;
}
 
Example #23
Source File: AnnotatedNode.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Visits the children of the given formula if it has not been visited already with
 * the given value of the negated flag and if formula.op==OR && negated or
 * formula.op==AND && !negated. Otherwise does nothing.
 * @see kodkod.ast.visitor.AbstractVoidVisitor#visit(kodkod.ast.NaryFormula)
 */
public void visit(NaryFormula formula) { 
	if (visited(formula)) return;
	final FormulaOperator op = formula.op();
	if ((!negated && op==AND) || (negated && op==OR)) { // op==AND || op==OR
		for(Formula child : formula) { 
			child.accept(this);
		}
	}
}
 
Example #24
Source File: PrettyPrinter.java    From quetzal with Eclipse Public License 2.0 5 votes vote down vote up
/** @return true if the given formula needs to be parenthesized if a 
 * child of a binary formula with the given operator */
private boolean parenthesize(FormulaOperator op, Formula child) { 
	return child instanceof QuantifiedFormula || 
	       (child instanceof BinaryFormula && 
	        (op==FormulaOperator.IMPLIES || 
	       ((BinaryFormula)child).op()!=op)) || 
	        ((child instanceof NaryFormula) && ((NaryFormula)child).op()!=op);
}
 
Example #25
Source File: Simplifier.java    From quetzal with Eclipse Public License 2.0 5 votes vote down vote up
public Formula visit(BinaryFormula expr) { 
	Formula ret = lookup(expr);
	if (ret!=null) return ret;
	final FormulaOperator op = expr.op();
	final Formula left = expr.left().accept(this);
	final Formula right = expr.right().accept(this);
	
	ret = simplify(op, left, right);
	
	if (ret==null) {
		ret = left==expr.left()&&right==expr.right() ? expr : left.compose(op, right);
	}
	
	return cache(expr,ret);
}
 
Example #26
Source File: PartialCannonicalizer.java    From quetzal with Eclipse Public License 2.0 5 votes vote down vote up
public Formula visit(BinaryFormula formula) { 
	Formula ret = lookup(formula);
	if (ret!=null) return ret;
	final FormulaOperator op = formula.op();
	if (op==FormulaOperator.AND) {
		final Set<Formula> conjuncts = kodkod.util.nodes.Nodes.roots(formula);
		if (conjuncts.size()>2) { 
			return cache(formula, Formula.and(conjuncts).accept(this));
		}
	}
	
	final Formula left = formula.left().accept(this);
	final Formula right = formula.right().accept(this);
	
	ret = simplify(op, left, right);
	
	if (ret==null) {
	
		final int hash = hash(op, left, right);
		for(Iterator<PartialCannonicalizer.Holder<Formula>> itr = formulas.get(hash); itr.hasNext(); ) {
			final Formula next = itr.next().obj;
			if (next instanceof BinaryFormula) { 
				final BinaryFormula hit = (BinaryFormula) next;
				if (hit.op()==op && hit.left()==left && hit.right()==right) { 
					return cache(formula, hit);
				}
			}
		}

		ret = left==formula.left()&&right==formula.right() ? formula : left.compose(op, right);
		formulas.add(new PartialCannonicalizer.Holder<Formula>(ret, hash));
	}
	
	return cache(formula,ret);
}
 
Example #27
Source File: Simplifier.java    From quetzal with Eclipse Public License 2.0 5 votes vote down vote up
/** @return a simplification of left op right, if possible, or null otherwise. */
final Formula simplify(FormulaOperator op, Formula left, Formula right) { 
	switch(op) { 
	case AND : 
		if (left==right)					{ return left; }
		else if (isTrue(left))				{ return right; }
		else if (isTrue(right))				{ return left; } 	
		else if (isFalse(left) || 
				 isFalse(right) || 
				 areInverses(left, right)) 	{ return Formula.FALSE; }
		break;
	case OR : 
		if (left==right)					{ return left; }
		else if (isFalse(left))				{ return right; }
		else if (isFalse(right))			{ return left; } 
		else if (isTrue(left) || 
				 isTrue(right) || 
				 areInverses(left, right)) 	{ return Formula.TRUE; }
		break;
	case IMPLIES : // !left or right
		if (left==right)					{ return Formula.TRUE; }
		else if (isTrue(left))				{ return right; }
		else if (isFalse(right)) 			{ return left; }
		else if (isFalse(left) || 
				 isTrue(right))				{ return Formula.TRUE; }
		break;
	case IFF : // (left and right) or (!left and !right)
		if (left==right)					{ return Formula.TRUE; }
		else if (isTrue(left))				{ return right; }
		else if (isFalse(left))				{ return right.not().accept(this); } 
		else if (isTrue(right))				{ return left; }
		else if (isFalse(right))			{ return left.not().accept(this); }
		else if (areInverses(left, right))	{ return Formula.FALSE; }
		break;
	default :
		Assertions.UNREACHABLE();
	}
	return null;
}
 
Example #28
Source File: Skolemizer.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * If not cached, visits the formula's children with appropriate settings
 * for the negated flag and the skolemDepth parameter.
 * @see kodkod.ast.visitor.AbstractReplacer#visit(kodkod.ast.NaryFormula)
 */
public final Formula visit(NaryFormula bf) {
	Formula ret = lookup(bf);
	if (ret!=null) return ret;			
	
	final int oldDepth = skolemDepth;
	final FormulaOperator op = bf.op();
	
	switch(op) { 
	case AND : if (negated)  skolemDepth = -1; break;
	case OR  : if (!negated) skolemDepth = -1; break;
	default  : throw new IllegalArgumentException("Unknown nary operator: " + op);
	}
	
	final Formula[] visited = new Formula[bf.size()];
	boolean allSame = true;
	for(int i = 0; i < visited.length; i++) { 
		final Formula child = bf.child(i);
		visited[i] = child.accept(this);
		allSame = allSame && (child==visited[i]);
	}
	ret = allSame ? bf : Formula.compose(op, visited);
	
	skolemDepth = oldDepth;
	
	return source(cache(bf,ret),bf);
}
 
Example #29
Source File: Formula.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Returns the composition of the given formulas using the given operator. 
 * @requires formulas.length != 2 => op.nary()
 * @return 
 * <pre> 
 *  formulas.length = 0 => constant(op=AND) else
 * 	formulas.length=1 => formulas[0] else 
 *  {e: Formula | e.children = formulas and e.op = this }
 * </pre>
 */
public static Formula compose(FormulaOperator op, Formula...formulas) { 
	switch(formulas.length) { 
	case 0 : 	
		switch(op) { 
		case AND : return TRUE;
		case OR : return FALSE;
		default : throw new IllegalArgumentException("Expected at least one argument: " + Arrays.toString(formulas));
		}
	case 1 : 	return formulas[0];
	case 2 : 	return new BinaryFormula(formulas[0], op, formulas[1]);
	default : 	return new NaryFormula(op, Containers.copy(formulas, new Formula[formulas.length]));
	}
}
 
Example #30
Source File: NaryFormula.java    From kodkod with MIT License 5 votes vote down vote up
/**  
 * Constructs a new composite Formula: op(children)
 * @requires children array is not modified while in use by this composite Formula
 * @requires some op.op[children]
 * @ensures this.children' = children && this.op' = op
 */
NaryFormula(FormulaOperator op, Formula[] children) { 
	assert children.length>2;
	if (!op.nary()) 
		throw new IllegalArgumentException("Cannot construct an nary formula using the non-nary operator " + op);
	this.op = op;
	this.children = children;
}