package org.batfish.z3.node; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.batfish.z3.NodProgram; import com.microsoft.z3.BoolExpr; import com.microsoft.z3.Context; import com.microsoft.z3.Z3Exception; public class IfExpr extends BooleanExpr implements ComplexExpr { private BooleanExpr _antecedent; private BooleanExpr _consequent; private List<Expr> _subExpressions; public IfExpr() { init(); } public IfExpr(BooleanExpr antecedent, BooleanExpr consequent) { init(); _antecedent = antecedent; _consequent = consequent; refreshSubExpressions(); } @Override public Set<String> getRelations() { Set<String> relations = new HashSet<>(); relations.addAll(_antecedent.getRelations()); relations.addAll(_consequent.getRelations()); return relations; } @Override public List<Expr> getSubExpressions() { return _subExpressions; } @Override public Set<String> getVariables() { Set<String> variables = new HashSet<>(); variables.addAll(_antecedent.getVariables()); variables.addAll(_consequent.getVariables()); return variables; } private void init() { _subExpressions = new ArrayList<>(); _printer = new ExpandedComplexExprPrinter(this); } private void refreshSubExpressions() { _subExpressions.clear(); _subExpressions.add(new IdExpr("=>")); _subExpressions.add(_antecedent); _subExpressions.add(_consequent); } public void setAntecedent(BooleanExpr antecedent) { _antecedent = antecedent; refreshSubExpressions(); } public void setConsequent(BooleanExpr consequent) { _consequent = consequent; refreshSubExpressions(); } @Override public BooleanExpr simplify() { BooleanExpr newAntecedent = _antecedent.simplify(); BooleanExpr newConsequent = _consequent.simplify(); if (newAntecedent == FalseExpr.INSTANCE || newConsequent == TrueExpr.INSTANCE) { return TrueExpr.INSTANCE; } else if (newAntecedent == TrueExpr.INSTANCE) { if (newConsequent == FalseExpr.INSTANCE) { return FalseExpr.INSTANCE; } else { return newConsequent; } } else if (newAntecedent != _antecedent || newConsequent != _consequent) { return new IfExpr(newAntecedent, newConsequent); } else { return this; } } @Override public BoolExpr toBoolExpr(NodProgram nodProgram) throws Z3Exception { Context ctx = nodProgram.getContext(); BoolExpr result = ctx.mkImplies(_antecedent.toBoolExpr(nodProgram), _consequent.toBoolExpr(nodProgram)); return result; } }