Java Code Examples for kodkod.ast.Formula#accept()

The following examples show how to use kodkod.ast.Formula#accept() . 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: AbstractReplacer.java    From kodkod with MIT License 6 votes vote down vote up
/** 
 * Calls lookup(formula) and returns the cached value, if any.  
 * If a replacement has not been cached, visits the formula's 
 * children.  If nothing changes, the argument is cached and
 * returned, otherwise a replacement formula is cached and returned.
 * @return { e: Expression | e.op = formula.op && #e.children = #formula.children && all i: [0..formula.children) | e.child(i) = formula.child(i).accept(this) }
 */
public Formula visit(NaryFormula formula) {
	Formula ret = lookup(formula);
	if (ret!=null) return ret;
	
	final Formula[] visited = new Formula[formula.size()];
	boolean allSame = true;
	for(int i = 0 ; i < visited.length; i++) { 
		final Formula child = formula.child(i);
		visited[i] = child.accept(this);
		allSame = allSame && visited[i]==child;
	}
	
	ret = allSame ? formula : Formula.compose(formula.op(), visited);
	return cache(formula,ret);
}
 
Example 2
Source File: PrenexNFConverter.java    From org.alloytools.alloy with Apache License 2.0 6 votes vote down vote up
@Override
public Formula visit(NaryFormula formula) {
    final ArrayList<Formula> children = new ArrayList<Formula>(formula.size());
    boolean allSame = true;
    boolean noQuant = true;
    for (Formula ch : formula) {
        Formula ch2 = ch.accept(this);
        allSame = allSame && ch == ch2;
        noQuant = noQuant && !(ch2 instanceof QuantifiedFormula);
        children.add(ch2);
    }
    Formula ans;
    if (allSame && noQuant) {
        ans = formula;
    } else {
        ans = children.get(0);
        for (int i = 1; i < children.size(); i++)
            ans = new Pair(ans, children.get(i)).compose(formula.op());
    }
    return saveMapping(ans, formula);
}
 
Example 3
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 4
Source File: HOLTranslator.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
@Override
public Proc visit(NaryFormula formula) {
    if (annotated.isFOLNode(formula))
        return new Proc.FOL(bounds, formula);
    Proc ans = null;
    for (Formula f : formula) {
        Proc p = formula.op() == FormulaOperator.OR ? toProc(f) : f.accept(this);
        ans = ans == null ? p : ans.compose(formula.op(), p);
    }
    return ans;
}
 
Example 5
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 6
Source File: Nodes.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Returns a minimal subset of {@linkplain #roots(Formula) roots} of the given formula such that all nodes in the given collection
 * are reachable from those roots.  The returned subset is a local minimum in that none of its members can be removed without leaving
 * some node in the descendants set unreachable from the remaining roots.
 * @requires descendants in formula.*components
 * @return { s: Set<Formula> | s.elements in roots(formula) and descendants in s.elements.*components and 
 * 				no s': Set<Formula> | s.containsAll(s') and s'.size()<s.size() and descendants in s.elements.*components }
 * @throws IllegalArgumentException  descendants !in formula.*components
 */
public static Set<Formula> minRoots(Formula formula, Collection<? extends Node> descendants) { 
	
	final Set<Node> desc = new IdentityHashSet<Node>(descendants);
	final VoidVisitor visitor = new AbstractVoidVisitor() {
		final Set<Node> visited = new IdentityHashSet<Node>();
		@Override
		protected boolean visited(Node n) {
			if (visited.add(n)) {
				desc.remove(n);
				return false;
			}
			return true;
		}
	};
	
	final Set<Formula> roots = new LinkedHashSet<Formula>();
	for(Formula root : roots(formula)) { 
		final int size = desc.size();
		root.accept(visitor);
		if (desc.size()<size) { roots.add(root); }
		if (desc.isEmpty()) { break; }
	}
	
	if (!desc.isEmpty()) 
		throw new IllegalArgumentException("descendants !in formula.*components: formula="+formula+" ; descendants="+descendants);
	
	return roots;
}
 
Example 7
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 8
Source File: AbstractDetector.java    From kodkod with MIT License 5 votes vote down vote up
/** 
 * Calls lookup(formula) and returns the cached value, if any.  
 * If no cached value exists, visits each child, caches the
 * disjunction of the children's return values and returns it. 
 * @return let x = lookup(formula) | 
 *          x != null => x,  
 *          cache(formula, formula.child(0).accept(this) || ... || formula.child(formula.size()-1).accept(this)) 
 */
public Boolean visit(NaryFormula formula) {
	final Boolean ret = lookup(formula);
	if (ret!=null) return ret;
	for(Formula child : formula) { 
		if (child.accept(this))
			return cache(formula, true);
	}
	return cache(formula, false);
}
 
Example 9
Source File: AbstractVoidVisitor.java    From kodkod with MIT License 5 votes vote down vote up
/**
 * Visits the children if this.visited(formula) returns false.  Otherwise does nothing.
 * @ensures all i: [0..#formula.children) | formula.child(i).accept(this)
 */
public void visit(NaryFormula formula) {
	if (visited(formula)) return;
	for(Formula child : formula) { 
		child.accept(this);
	}
}
 
Example 10
Source File: AnnotatedNode.java    From org.alloytools.alloy with Apache License 2.0 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)
 */
@Override
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 11
Source File: Nodes.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a minimal subset of {@linkplain #roots(Formula) roots} of the given
 * formula such that all nodes in the given collection are reachable from those
 * roots. The returned subset is a local minimum in that none of its members can
 * be removed without leaving some node in the descendants set unreachable from
 * the remaining roots.
 *
 * @requires descendants in formula.*components
 * @return { s: Set<Formula> | s.elements in roots(formula) and descendants in
 *         s.elements.*components and no s': Set<Formula> | s.containsAll(s')
 *         and s'.size()<s.size() and descendants in s.elements.*components }
 * @throws IllegalArgumentException descendants !in formula.*components
 */
public static Set<Formula> minRoots(Formula formula, Collection< ? extends Node> descendants) {

    final Set<Node> desc = new IdentityHashSet<Node>(descendants);
    final VoidVisitor visitor = new AbstractVoidVisitor() {

        final Set<Node> visited = new IdentityHashSet<Node>();

        @Override
        protected boolean visited(Node n) {
            if (visited.add(n)) {
                desc.remove(n);
                return false;
            }
            return true;
        }
    };

    final Set<Formula> roots = new LinkedHashSet<Formula>();
    for (Formula root : roots(formula)) {
        final int size = desc.size();
        root.accept(visitor);
        if (desc.size() < size) {
            roots.add(root);
        }
        if (desc.isEmpty()) {
            break;
        }
    }

    if (!desc.isEmpty())
        throw new IllegalArgumentException("descendants !in formula.*components: formula=" + formula + " ; descendants=" + descendants);

    return roots;
}
 
Example 12
Source File: Skolemizer.java    From org.alloytools.alloy with Apache License 2.0 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)
 */
@Override
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 13
Source File: FormulaFlattener.java    From kodkod with MIT License 5 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)
 */
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 14
Source File: AbstractDetector.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/**
 * Calls lookup(formula) and returns the cached value, if any. If no cached
 * value exists, visits each child, caches the disjunction of the children's
 * return values and returns it.
 *
 * @return let x = lookup(formula) | x != null => x, cache(formula,
 *         formula.child(0).accept(this) || ... ||
 *         formula.child(formula.size()-1).accept(this))
 */
@Override
public Boolean visit(NaryFormula formula) {
    final Boolean ret = lookup(formula);
    if (ret != null)
        return ret;
    for (Formula child : formula) {
        if (child.accept(this))
            return cache(formula, true);
    }
    return cache(formula, false);
}
 
Example 15
Source File: AbstractVoidVisitor.java    From org.alloytools.alloy with Apache License 2.0 5 votes vote down vote up
/**
 * Visits the children if this.visited(formula) returns false. Otherwise does
 * nothing.
 *
 * @ensures all i: [0..#formula.children) | formula.child(i).accept(this)
 */
@Override
public void visit(NaryFormula formula) {
    if (visited(formula))
        return;
    for (Formula child : formula) {
        child.accept(this);
    }
}
 
Example 16
Source File: FOL2BoolTranslator.java    From org.alloytools.alloy with Apache License 2.0 4 votes vote down vote up
/**
 * Translates the given existentially quantified formula as follows (where
 * A_0...A_|A| stand for boolean variables that represent the tuples of the
 * expression A, etc.): let quantFormula = "some a: A, b: B, ..., x: X | F(a, b,
 * ..., x)" | (A_0 && B_0 && ... && X_0 && translate(F(A_0, B_0, ..., X_0))) ||
 * ... || (A_|A| && B_|B| && ... && X_|X| && translate(F(A_|A|, B_|B|, ...,
 * X_|X|)) If the noOverflow option is specified, then the translation looks
 * like: let quantFormula = "some a: A, b: B, ..., x: X | F(a, b, ..., x)" |
 * (A_0 && B_0 && ... && X_0 && !of(F(A_0, B_0, ..., X_0)) && translate(F(A_0,
 * B_0, ..., X_0))) || ... || (A_|A| && B_|B| && ... && X_|X| && !of(F(A_|A|,
 * B_|B|, ..., X_|X|)) && translate(F(A_|A|, B_|B|, ..., X_|X|)) where
 * of(F(A_|a|, B_|b|, ..., X_|x|)) is the portion of the overflow circuit
 * generated by the translation of F(A_|a|, B_|b|, ..., X_|x|) contributed by
 * arithmetic operations over only the integer variables of this quantifier
 *
 * @param decls formula declarations
 * @param formula the formula body
 * @param currentDecl currently processed declaration; should be 0 initially
 * @param declConstraints the constraints implied by the declarations; should be
 *            Boolean.TRUE intially
 * @param acc the accumulator that contains the top level conjunction; should be
 *            an empty OR accumulator initially
 * @ensures the given accumulator contains the translation of the formula "some
 *          decls | formula"
 */
private void some(Decls decls, Formula formula, int currentDecl, BooleanValue declConstraints, BooleanAccumulator acc) {
    if (acc.isShortCircuited())
        return;
    final BooleanFactory factory = interpreter.factory();

    if (decls.size() == currentDecl) {
        BooleanValue formulaCircuit = formula.accept(this);
        BooleanValue finalCircuit = factory.and(declConstraints, formulaCircuit);
        acc.add(finalCircuit);
        return;
    }

    final Decl decl = decls.get(currentDecl);
    final BooleanMatrix declTransl = visit(decl);
    final BooleanMatrix groundValue = factory.matrix(declTransl.dimensions());
    env = env.extend(decl.variable(), decl.expression(), groundValue, Quantifier.SOME);
    for (IndexedEntry<BooleanValue> entry : declTransl) {
        groundValue.set(entry.index(), BooleanConstant.TRUE);
        some(decls, formula, currentDecl + 1, factory.and(entry.value(), declConstraints), acc);
        groundValue.set(entry.index(), BooleanConstant.FALSE);
    }
    env = env.parent();
}
 
Example 17
Source File: FOL2BoolTranslator.java    From org.alloytools.alloy with Apache License 2.0 4 votes vote down vote up
/**
 * Translates the given universally quantified formula as follows (where
 * A_0...A_|A| stand for boolean variables that represent the tuples of the
 * expression A, etc.): let quantFormula = "all a: A, b: B, ..., x: X | F(a, b,
 * ..., x)" | (A_0 && B_0 && ... && X_0 => translate(F(A_0, B_0, ..., X_0))) &&
 * ... && (A_|A| && B_|B| && ... && X_|X| => translate(F(A_|A|, B_|B|, ...,
 * X_|X|))) If the noOverflow option is specified, then the translation looks
 * like: let quantFormula = "all a: A, b: B, ..., x: X | F(a, b, ..., x)" | (A_0
 * && B_0 && ... && X_0 => (!of(F(A_0, B_0, ..., X_0)) => translate(F(A_0, B_0,
 * ..., X_0)))) && ... && (A_|A| && B_|B| && ... && X_|X| => (!of(F(A_|A|,
 * B_|B|, ..., X_|X|)) => translate(F(A_|A|, B_|B|, ..., X_|X|)))) where
 * of(F(A_|a|, B_|b|, ..., X_|x|)) is the portion of the overflow circuit
 * generated by the translation of F(A_|a|, B_|b|, ..., X_|x|) contributed by
 * arithmetic operations over only the integer variables of this quantifier
 *
 * @param decls formula declarations
 * @param formula the formula body
 * @param currentDecl currently processed declaration; should be 0 initially
 * @param declConstraints the constraints implied by the declarations; should be
 *            Boolean.FALSE initially
 * @param acc the accumulator that contains the top level conjunction; should be
 *            an empty AND accumulator initially
 * @ensures the given accumulator contains the translation of the formula "all
 *          decls | formula"
 */
private void all(Decls decls, Formula formula, int currentDecl, BooleanValue declConstraints, BooleanAccumulator acc) {
    if (acc.isShortCircuited())
        return;
    final BooleanFactory factory = interpreter.factory();

    if (decls.size() == currentDecl) {
        BooleanValue formulaCircuit = formula.accept(this);
        BooleanValue finalCircuit = factory.or(declConstraints, formulaCircuit);
        acc.add(finalCircuit);
        return;
    }

    final Decl decl = decls.get(currentDecl);
    final BooleanMatrix declTransl = visit(decl);
    final BooleanMatrix groundValue = factory.matrix(declTransl.dimensions());
    env = env.extend(decl.variable(), decl.expression(), groundValue, Quantifier.ALL);
    for (IndexedEntry<BooleanValue> entry : declTransl) {
        groundValue.set(entry.index(), BooleanConstant.TRUE);
        all(decls, formula, currentDecl + 1, factory.or(factory.not(entry.value()), declConstraints), acc);
        groundValue.set(entry.index(), BooleanConstant.FALSE);
    }
    env = env.parent();
}
 
Example 18
Source File: ResolutionBasedProof.java    From org.alloytools.alloy with Apache License 2.0 4 votes vote down vote up
/**
 * Returns the connected core based on the given set of core variables.
 *
 * @requires coreVar = StrategyUtils.coreVars(solver.proof());
 * @return let formulas = (this.log.records[int] & literal.{i: int | abs(i) in
 *         coreVars}).formula | connected = {f: formulas | some s: set coreNodes
 *         | f + this.log.formula in s and (s - this.log.formula).~components in
 *         s }
 */
private Set<Formula> connectedCore(final IntSet coreVars) {
    final Set<Formula> coreNodes = new IdentityHashSet<Formula>();
    final RecordFilter filter = new RecordFilter() {

        @Override
        public boolean accept(Node node, Formula translated, int literal, Map<Variable,TupleSet> env) {
            return coreVars.contains(StrictMath.abs(literal));
        }
    };
    for (Iterator<TranslationRecord> itr = log().replay(filter); itr.hasNext();) {
        coreNodes.add(itr.next().translated());
    }
    final Set<Formula> connected = new IdentityHashSet<Formula>();
    final AbstractVoidVisitor traverser = new AbstractVoidVisitor() {

        final Set<Node> visited = new IdentityHashSet<Node>();

        /**
         * Returns true if the given node has been visited before or if it is not
         * contained in this.nodes set. Otherwise adds the node to the connected set and
         * returns false.
         *
         * @ensures this.visited' = this.visited + n
         * @ensures n !in this.visited && n in coreNodes => connected' = connected + n
         *          else connected' = connected
         * @return n in visited || n !in coreNodes
         */
        @Override
        protected boolean visited(Node n) {
            if (visited.add(n) && coreNodes.contains(n)) {
                connected.add((Formula) n);
                return false;
            }
            return true;
        }
    };
    for (Formula root : log().roots()) {
        root.accept(traverser);
    }
    return connected;
}
 
Example 19
Source File: PrettyPrinter.java    From org.alloytools.alloy with Apache License 2.0 3 votes vote down vote up
/**
 * Returns a pretty-printed string representation of the given formulas, with
 * each line offset by at least the given number of whitespaces. The line
 * parameter determines the length of each pretty-printed line, including the
 * offset.
 *
 * @requires 0 <= offset < line
 * @return a pretty-printed string representation of the given formulas
 */
public static String print(Set<Formula> formulas, int offset, int line) {
    final Formatter formatter = new Formatter(offset, line);
    for (Formula f : formulas) {
        f.accept(formatter);
        formatter.newline();
    }
    return formatter.tokens.toString();
}
 
Example 20
Source File: PrettyPrinter.java    From kodkod with MIT License 3 votes vote down vote up
/**
 * Returns a pretty-printed string representation of the 
 * given formulas, with each line offset by at least the given
 * number of whitespaces.  The line parameter determines the
 * length of each pretty-printed line, including the offset.
 * @requires 0 <= offset < line
 * @return a pretty-printed string representation of the 
 * given formulas
 */
public static String print(Set<Formula> formulas, int offset, int line) { 
	final Formatter formatter = new Formatter(offset,line);
	for(Formula f : formulas) { 
		f.accept(formatter);
		formatter.newline();
	}
	return formatter.tokens.toString();
}