Browse Source

accumulation: Enable parsing of U+ Formulas

accumulation
Sascha Wunderlich 8 years ago
parent
commit
b707e2def3
  1. 6
      prism/src/explicit/AccumulationProduct.java
  2. 38
      prism/src/parser/PrismParser.jj
  3. 10
      prism/src/parser/ast/ExpressionAccumulation.java
  4. 72
      prism/src/parser/visitor/ReplaceAccumulationExpression.java

6
prism/src/explicit/AccumulationProduct.java

@ -119,21 +119,25 @@ public abstract class AccumulationProduct<M extends Model,Component> extends Pro
// For DIA operators, we just check the bound. // For DIA operators, we just check the bound.
// For BOX operators, we check the INVERTED bound. // For BOX operators, we check the INVERTED bound.
// TODO: THIS MAY BE BROKEN
switch(accexp.getSymbol()) { switch(accexp.getSymbol()) {
case ACCBOXMINUS: case ACCBOXMINUS:
case ACCBOXPLUS: case ACCBOXPLUS:
if (!rhs.isInBounds(lhs)) { if (!rhs.isInBounds(lhs)) {
isGood = true; isGood = true;
} }
mc.getLog().println("WARNING: This may be wrong.");
break; break;
case ACCDIAMINUS: case ACCDIAMINUS:
case ACCDIAPLUS: case ACCDIAPLUS:
case ACCUNTIL:
if (rhs.isInBounds(lhs)) { if (rhs.isInBounds(lhs)) {
isGood = true; isGood = true;
} }
break; break;
default: default:
throw new RuntimeException("Oh boy!");
throw new RuntimeException("Accumulation symbol cannot be handled...");
} }
//if(isGood) {mc.getLog().print("+");} else {mc.getLog().print("-");} //if(isGood) {mc.getLog().print("+");} else {mc.getLog().print("-");}
return isGood; return isGood;

38
prism/src/parser/PrismParser.jj

@ -1152,10 +1152,18 @@ Expression ExpressionTemporalBinary(boolean prop, boolean pathprop) :
TemporalOperatorBound defaultBound = null; TemporalOperatorBound defaultBound = null;
TemporalOperatorBounds bounds = null; TemporalOperatorBounds bounds = null;
Token begin = null; Token begin = null;
//Accumulation
ExpressionAccumulation accexp;
AccumulationConstraint constr;
TemporalOperatorBound bound;
Expression reg;
ArrayList<Expression> fireOn;
} }
{ {
{ begin = getToken(1); } ret = ExpressionTemporalUnary(prop, pathprop) { begin = getToken(1); } ret = ExpressionTemporalUnary(prop, pathprop)
[
(
// This production is only allowed in expressions if the "pathprop" parameter is true // This production is only allowed in expressions if the "pathprop" parameter is true
{ if (!pathprop) throw generateParseException(); } { if (!pathprop) throw generateParseException(); }
{ exprTemp = new ExpressionTemporal(); exprTemp.setOperand1(ret); } { exprTemp = new ExpressionTemporal(); exprTemp.setOperand1(ret); }
@ -1167,7 +1175,33 @@ Expression ExpressionTemporalBinary(boolean prop, boolean pathprop) :
)? )?
expr = ExpressionTemporalUnary(prop, pathprop) expr = ExpressionTemporalUnary(prop, pathprop)
{ exprTemp.setOperand2(expr); exprTemp.setPosition(begin, getToken(0)); ret = exprTemp; } { exprTemp.setOperand2(expr); exprTemp.setPosition(begin, getToken(0)); ret = exprTemp; }
]
|
// Accumulation symbol
<ACCUNTIL> { accexp = new ExpressionAccumulation(AccumulationSymbol.ACCUNTIL); accexp.setOperand1(ret); }
// Regular expression, should be star-free
<LPARENTH>
(
( <REGEXP_MARKER> reg = ExpressionRegularUnary(prop, false) { accexp.setRegularExpression((ExpressionRegular)reg); } )
| ( bound = BoundExpression() { accexp.setBoundExpression(bound); } )
)
<RPARENTH>
// Weight constraint
<LPARENTH>
(
constr = ExpressionAccumulationConstraint()
{ accexp.setConstraint(constr); }
)
<RPARENTH>
// Fire set (= !StutterSet)
(<LPARENTH>
(
fireOn = ExpressionAccumulationFire()
{ accexp.setFireOn(fireOn); }
)
<RPARENTH>)?
ret = ExpressionTemporalUnary(prop, pathprop)
{ accexp.setOperand2(ret); ret = accexp; }
)?
{ return ret; } { return ret; }
} }

10
prism/src/parser/ast/ExpressionAccumulation.java

@ -27,6 +27,7 @@
package parser.ast; package parser.ast;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.stream.Collectors;
import param.BigRational; import param.BigRational;
import parser.EvaluateContext; import parser.EvaluateContext;
@ -125,7 +126,7 @@ public class ExpressionAccumulation extends Expression
public String toString() { public String toString() {
String ret = ""; String ret = "";
if(operand1 != null) { ret += operand1.toString(); }
if(operand1 != null) { ret += operand1.toString() + " "; }
ret += symbol.toString(); ret += symbol.toString();
@ -135,9 +136,12 @@ public class ExpressionAccumulation extends Expression
ret += "(" + constraint.toString() + ")"; ret += "(" + constraint.toString() + ")";
if ( hasFireOn() ) { ret += "(" + fireOn.toString() + ")"; }
if ( hasFireOn() ) {
String fireOnString = fireOn.stream().map(f -> f.toString()).collect(Collectors.joining(","));
ret += "(" + fireOnString + ")";
}
if(operand2 != null) { ret += operand2.toString(); }
if(operand2 != null) { ret += " " + operand2.toString(); }
return ret; return ret;
} }

72
prism/src/parser/visitor/ReplaceAccumulationExpression.java

@ -39,51 +39,47 @@ public class ReplaceAccumulationExpression extends ASTTraverseModify {
if (sym.isMinus()) { if (sym.isMinus()) {
throw(new PrismLangException("Accumulation with past is not supported.")); throw(new PrismLangException("Accumulation with past is not supported."));
} }
// This expression is of the form OR{0..(l-1)}(init_i AND (run_i UNTIL goal_i))
if (sym.isUntil()) {
throw(new PrismLangException("ACCUNTIL is not supported."));
} else {
// This expression is of the form OR{0..(l-1)}(init_i AND (run_i UNTIL goal_i))
// Build all the subexpressions...
ArrayList<ExpressionBinaryOp> clauses = new ArrayList<>();
Expression result = null;
// Build all the subexpressions...
ArrayList<ExpressionBinaryOp> clauses = new ArrayList<>();
Expression result = null;
for(int i=0; i<accLength; i++) {
Expression init = new ExpressionLabel(initLabels.get(i));
Expression run = new ExpressionLabel(runLabels.get(i));
Expression goal = new ExpressionLabel(goalLabels.get(i));
for(int i=0; i<accLength; i++) {
Expression init = new ExpressionLabel(initLabels.get(i));
Expression run = new ExpressionLabel(runLabels.get(i));
Expression goal = new ExpressionLabel(goalLabels.get(i));
// if this is until:
// append first operand to run
// append second operand to goal
if(accexp.getOperand1() != null) {
run = new ExpressionBinaryOp(ExpressionBinaryOp.AND, run, accexp.getOperand1());
}
if(accexp.getOperand2() != null) {
goal = new ExpressionBinaryOp(ExpressionBinaryOp.AND, goal, accexp.getOperand2());
}
// until: (run_i UNTIL goal_i)
ExpressionTemporal until = new ExpressionTemporal(ExpressionTemporal.P_U, run, goal);
// and: (init_i AND until)
ExpressionBinaryOp and = new ExpressionBinaryOp(ExpressionBinaryOp.AND, init, until);
clauses.add(and);
if(i==0) {
result = and;
} else {
result = new ExpressionBinaryOp(ExpressionBinaryOp.OR, result, and);
}
// if this is until:
// append first operand to run
// append second operand to goal
if(accexp.getOperand1() != null) {
run = new ExpressionBinaryOp(ExpressionBinaryOp.AND, run, accexp.getOperand1());
}
if(accexp.getOperand2() != null) {
goal = new ExpressionBinaryOp(ExpressionBinaryOp.AND, goal, accexp.getOperand2());
} }
// If its a BOX, negate it
if (sym.isBox()) {
return new ExpressionUnaryOp(ExpressionUnaryOp.NOT, result);
// until: (run_i UNTIL goal_i)
ExpressionTemporal until = new ExpressionTemporal(ExpressionTemporal.P_U, run, goal);
// and: (init_i AND until)
ExpressionBinaryOp and = new ExpressionBinaryOp(ExpressionBinaryOp.AND, init, until);
clauses.add(and);
if(i==0) {
result = and;
} else { } else {
return result;
result = new ExpressionBinaryOp(ExpressionBinaryOp.OR, result, and);
} }
} }
// If its a BOX, negate it
if (sym.isBox()) {
return new ExpressionUnaryOp(ExpressionUnaryOp.NOT, result);
} else {
return result;
}
} else { } else {
return expr; return expr;
} }

Loading…
Cancel
Save