Browse Source

accumulation: Enable parsing of U+ Formulas

accumulation
Sascha Wunderlich 7 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 BOX operators, we check the INVERTED bound.
// TODO: THIS MAY BE BROKEN
switch(accexp.getSymbol()) {
case ACCBOXMINUS:
case ACCBOXPLUS:
if (!rhs.isInBounds(lhs)) {
isGood = true;
}
mc.getLog().println("WARNING: This may be wrong.");
break;
case ACCDIAMINUS:
case ACCDIAPLUS:
case ACCUNTIL:
if (rhs.isInBounds(lhs)) {
isGood = true;
}
break;
default:
throw new RuntimeException("Oh boy!");
throw new RuntimeException("Accumulation symbol cannot be handled...");
}
//if(isGood) {mc.getLog().print("+");} else {mc.getLog().print("-");}
return isGood;

38
prism/src/parser/PrismParser.jj

@ -1152,10 +1152,18 @@ Expression ExpressionTemporalBinary(boolean prop, boolean pathprop) :
TemporalOperatorBound defaultBound = null;
TemporalOperatorBounds bounds = null;
Token begin = null;
//Accumulation
ExpressionAccumulation accexp;
AccumulationConstraint constr;
TemporalOperatorBound bound;
Expression reg;
ArrayList<Expression> fireOn;
}
{
{ begin = getToken(1); } ret = ExpressionTemporalUnary(prop, pathprop)
[
(
// This production is only allowed in expressions if the "pathprop" parameter is true
{ if (!pathprop) throw generateParseException(); }
{ exprTemp = new ExpressionTemporal(); exprTemp.setOperand1(ret); }
@ -1167,7 +1175,33 @@ Expression ExpressionTemporalBinary(boolean prop, boolean pathprop) :
)?
expr = ExpressionTemporalUnary(prop, pathprop)
{ 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; }
}

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

@ -27,6 +27,7 @@
package parser.ast;
import java.util.ArrayList;
import java.util.stream.Collectors;
import param.BigRational;
import parser.EvaluateContext;
@ -125,7 +126,7 @@ public class ExpressionAccumulation extends Expression
public String toString() {
String ret = "";
if(operand1 != null) { ret += operand1.toString(); }
if(operand1 != null) { ret += operand1.toString() + " "; }
ret += symbol.toString();
@ -135,9 +136,12 @@ public class ExpressionAccumulation extends Expression
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;
}

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

@ -39,51 +39,47 @@ public class ReplaceAccumulationExpression extends ASTTraverseModify {
if (sym.isMinus()) {
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 {
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 {
return expr;
}

Loading…
Cancel
Save