|
|
|
@ -1,10 +1,13 @@ |
|
|
|
package parser.visitor; |
|
|
|
|
|
|
|
import java.util.ArrayList; |
|
|
|
|
|
|
|
import parser.ast.AccumulationSymbol; |
|
|
|
import parser.ast.Expression; |
|
|
|
import parser.ast.ExpressionAccumulation; |
|
|
|
import parser.ast.ExpressionBinaryOp; |
|
|
|
import parser.ast.ExpressionLabel; |
|
|
|
import parser.ast.ExpressionTemporal; |
|
|
|
import parser.ast.ExpressionUnaryOp; |
|
|
|
import parser.ast.TemporalOperatorBound; |
|
|
|
import parser.ast.TemporalOperatorBounds; |
|
|
|
import prism.IntegerBound; |
|
|
|
@ -15,12 +18,14 @@ public class ReplaceAccumulationExpressionSimple extends ASTTraverseModify { |
|
|
|
private ExpressionAccumulation accexp; |
|
|
|
private String goodLabel; |
|
|
|
private int accLength; |
|
|
|
private boolean untilConstr; |
|
|
|
|
|
|
|
public ReplaceAccumulationExpressionSimple(ExpressionAccumulation accexp, String goodLabel, int accLength) { |
|
|
|
public ReplaceAccumulationExpressionSimple(ExpressionAccumulation accexp, String goodLabel, int accLength, boolean untilConstr) { |
|
|
|
super(); |
|
|
|
this.accexp = accexp; |
|
|
|
this.goodLabel = goodLabel; |
|
|
|
this.accLength = accLength; |
|
|
|
this.untilConstr = untilConstr; |
|
|
|
} |
|
|
|
|
|
|
|
private Object replaceWithReach(ExpressionAccumulation expr) throws PrismLangException { |
|
|
|
@ -28,32 +33,76 @@ public class ReplaceAccumulationExpressionSimple extends ASTTraverseModify { |
|
|
|
|
|
|
|
ExpressionLabel label = new ExpressionLabel(goodLabel); |
|
|
|
|
|
|
|
if (sym.isBox()) { |
|
|
|
throw new PrismLangException("This is a box, which should have been replaced already!"); |
|
|
|
} |
|
|
|
|
|
|
|
if (sym.isPlus()) { |
|
|
|
ExpressionTemporal fExpr = new ExpressionTemporal(ExpressionTemporal.P_F, null, label); |
|
|
|
TemporalOperatorBounds fBounds = new TemporalOperatorBounds(); |
|
|
|
TemporalOperatorBound fBound = IntegerBound.fromEqualBounds(accLength).toTemporalOperatorBound(); |
|
|
|
fBounds.setDefaultBound(fBound); |
|
|
|
fExpr.setBounds(fBounds); |
|
|
|
// If its a BOX, negate it |
|
|
|
if (sym.isBox()) { |
|
|
|
return new ExpressionUnaryOp(ExpressionUnaryOp.NOT, fExpr); |
|
|
|
} else { |
|
|
|
return fExpr; |
|
|
|
} |
|
|
|
return fExpr; |
|
|
|
} else { //isMinus |
|
|
|
if (sym.isBox()) { |
|
|
|
return new ExpressionUnaryOp(ExpressionUnaryOp.NOT, label); |
|
|
|
} else { |
|
|
|
return label; |
|
|
|
return label; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//TODO: Fixme |
|
|
|
private Object replaceWithUntilCascade(ExpressionAccumulation expr) throws PrismLangException { |
|
|
|
AccumulationSymbol sym = accexp.getSymbol(); |
|
|
|
if(sym.isMinus()) { |
|
|
|
throw new PrismLangException("Tried to handle past with untilCascade. Bailing..."); |
|
|
|
} |
|
|
|
|
|
|
|
ExpressionLabel label = new ExpressionLabel(goodLabel); |
|
|
|
|
|
|
|
Expression current = label; |
|
|
|
|
|
|
|
// TODO: moveme |
|
|
|
Expression notfiltered = Expression.True(); |
|
|
|
if(accexp.hasFireOn()) { |
|
|
|
// Build the fireOn expressions |
|
|
|
ArrayList<Expression> fireOn = accexp.getFireOn(); |
|
|
|
|
|
|
|
notfiltered = fireOn.get(0); |
|
|
|
for(int i=1;i<fireOn.size();i++) { |
|
|
|
notfiltered = new ExpressionBinaryOp(ExpressionBinaryOp.OR, notfiltered, fireOn.get(i)); |
|
|
|
} |
|
|
|
System.out.println("notfiltered: " + notfiltered); |
|
|
|
} |
|
|
|
|
|
|
|
Expression filtered = Expression.Not(notfiltered); |
|
|
|
|
|
|
|
// Build the following tree: |
|
|
|
// U |
|
|
|
// filtered and |
|
|
|
// notfil next |
|
|
|
// current |
|
|
|
for(int i=0;i<accLength;i++) { |
|
|
|
// X current |
|
|
|
ExpressionTemporal xCurrent = new ExpressionTemporal(ExpressionTemporal.P_X, null, current); |
|
|
|
|
|
|
|
// notfil & xCurrent |
|
|
|
ExpressionBinaryOp and = new ExpressionBinaryOp(ExpressionBinaryOp.AND, notfiltered, xCurrent); |
|
|
|
|
|
|
|
// filtered U and |
|
|
|
ExpressionTemporal until = new ExpressionTemporal(ExpressionTemporal.P_U, filtered, and); |
|
|
|
|
|
|
|
// Set this for the next round |
|
|
|
current = Expression.Parenth(until); |
|
|
|
} |
|
|
|
|
|
|
|
return current; |
|
|
|
} |
|
|
|
|
|
|
|
public Object visit(ExpressionAccumulation expr) throws PrismLangException |
|
|
|
{ |
|
|
|
if (expr == accexp) { |
|
|
|
// This is a simple accumulation expression. Rewrite to F=.... |
|
|
|
return replaceWithReach(expr); |
|
|
|
// This is a simple accumulation expression. Rewrite to F=.... or to until cascade |
|
|
|
if (untilConstr) { return replaceWithUntilCascade(expr); } |
|
|
|
else { return replaceWithReach(expr); } |
|
|
|
} else { |
|
|
|
return expr; |
|
|
|
} |
|
|
|
|