001package org.clafer.ir;
002
003import java.util.ArrayList;
004import java.util.Collections;
005import java.util.HashSet;
006import java.util.List;
007import java.util.Set;
008import org.clafer.common.Check;
009
010/**
011 * The compiled model in IR. A module contains variables and constraints. The IR
012 * is permitted to throw away any variables during the optimization.
013 *
014 * @author jimmy
015 */
016public class IrModule {
017
018    private final Set<IrVar> variables;
019    private final List<IrBoolExpr> constraints;
020
021    public IrModule() {
022        this(100, 100);
023    }
024
025    public IrModule(int initialVariableCapacity, int initialConstraintCapacity) {
026        this.variables = new HashSet<>(initialVariableCapacity);
027        this.constraints = new ArrayList<>(initialConstraintCapacity);
028    }
029
030    public IrModule addVariable(IrVar var) {
031        if (!(var instanceof IrConstant)) {
032            variables.add(var);
033        }
034        return this;
035    }
036
037    public IrModule addVariables(IrVar... vars) {
038        for (IrVar var : vars) {
039            addVariable(var);
040        }
041        return this;
042    }
043
044    public IrModule addVariables(Iterable<? extends IrVar> vars) {
045        for (IrVar var : vars) {
046            addVariable(var);
047        }
048        return this;
049    }
050
051    public Set<IrVar> getVariables() {
052        return Collections.unmodifiableSet(variables);
053    }
054
055    public IrModule addConstraint(IrBoolExpr expr) {
056        Check.notNull(expr);
057        if (expr instanceof IrAnd) {
058            IrAnd and = (IrAnd) expr;
059            for (IrBoolExpr operand : and.getOperands()) {
060                addConstraint(operand);
061            }
062        } else if (expr instanceof IrNotImplies) {
063            IrNotImplies notImplies = (IrNotImplies) expr;
064            addConstraint(notImplies.getAntecedent());
065            addConstraint(Irs.not(notImplies.getConsequent()));
066        } else if (!IrUtil.isTrue(expr)) {
067            constraints.add(expr);
068        }
069        return this;
070    }
071
072    public IrModule addConstraints(IrBoolExpr... exprs) {
073        for (IrBoolExpr expr : exprs) {
074            addConstraint(expr);
075        }
076        return this;
077    }
078
079    public IrModule addConstraints(Iterable<? extends IrBoolExpr> exprs) {
080        for (IrBoolExpr expr : exprs) {
081            addConstraint(expr);
082        }
083        return this;
084    }
085
086    public List<IrBoolExpr> getConstraints() {
087        return Collections.unmodifiableList(constraints);
088    }
089
090    @Override
091    public String toString() {
092        StringBuilder result = new StringBuilder();
093        result.append("IrModule").append('\n');
094        for (IrVar variable : variables) {
095            result.append("++").append(variable).append('\n');
096        }
097        for (IrBoolExpr constraint : constraints) {
098            result.append("--").append(constraint).append('\n');
099        }
100        return result.toString();
101    }
102}