Skip to content
Snippets Groups Projects
Commit 94e06eff authored by Jan Gruteser's avatar Jan Gruteser
Browse files

refactor operation handling

parent 19c9592d
Branches
No related tags found
No related merge requests found
...@@ -2,109 +2,105 @@ package de.tla2b.analysis; ...@@ -2,109 +2,105 @@ package de.tla2b.analysis;
import de.be4.classicalb.core.parser.node.*; import de.be4.classicalb.core.parser.node.*;
import de.tla2b.global.BBuiltInOPs; import de.tla2b.global.BBuiltInOPs;
import de.tla2b.global.TranslationGlobals;
import de.tla2b.types.TLAType;
import de.tla2bAst.BAstCreator; import de.tla2bAst.BAstCreator;
import tla2sany.semantic.*; import tla2sany.semantic.*;
import tlc2.tool.BuiltInOPs; import tlc2.tool.BuiltInOPs;
import java.util.*; import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class BOperation extends BuiltInOPs implements TranslationGlobals { import static de.be4.classicalb.core.parser.util.ASTBuilder.createConjunction;
import static de.be4.classicalb.core.parser.util.ASTBuilder.createIdentifier;
import static de.tla2b.global.TranslationGlobals.SUBSTITUTE_PARAM;
public class BOperation extends BuiltInOPs {
private final String name; private final String name;
private final OpApplNode node; private final OpApplNode node;
private final List<OpApplNode> existQuans; private final List<OpApplNode> existQuans;
private List<String> opParams; private final List<FormalParamNode> formalParams = new ArrayList<>();
private List<FormalParamNode> formalParams; private final List<OpDeclNode> unchangedVariables = new ArrayList<>();
private List<String> unchangedVariables; private final List<ExprOrOpArgNode> guards = new ArrayList<>();
private final List<OpDeclNode> unchangedVariablesList; private final List<ExprOrOpArgNode> beforeAfterPredicates = new ArrayList<>();
private final List<ExprOrOpArgNode> guards; private final Map<OpDeclNode, ExprOrOpArgNode> assignments = new LinkedHashMap<>();
private final List<ExprOrOpArgNode> beforeAfterPredicates; private final List<OpDeclNode> anyVariables = new ArrayList<>();
private final Map<SymbolNode, ExprOrOpArgNode> assignments = new LinkedHashMap<>();
private List<OpDeclNode> anyVariables;
private final SpecAnalyser specAnalyser;
public BOperation(String name, OpApplNode n, List<OpApplNode> existQuans, SpecAnalyser specAnalyser) { public BOperation(String name, OpApplNode n, List<OpApplNode> existQuans, SpecAnalyser specAnalyser) {
this.name = name; this.name = name;
this.node = n; this.node = n;
this.existQuans = existQuans; this.existQuans = existQuans;
this.specAnalyser = specAnalyser; OpDeclNode[] variableDecls = specAnalyser.getModuleNode().getVariableDecls();
this.unchangedVariablesList = new ArrayList<>(); this.anyVariables.addAll(Arrays.asList(variableDecls));
this.guards = new ArrayList<>();
this.beforeAfterPredicates = new ArrayList<>();
anyVariables = new ArrayList<>(Arrays.asList(specAnalyser.getModuleNode().getVariableDecls()));
evalParams(); // eval params
// System.out.println("Construction B Operation for TLA+ action: " + name); for (OpApplNode ex : existQuans) {
findUnchangedVariables(); for (FormalParamNode[] param : ex.getBdedQuantSymbolLists()) { // (bounded exists)
formalParams.addAll(Arrays.asList(param));
}
}
// DebugUtils.printDebugMsg("Constructing B Operation for TLA+ action: " + name);
findUnchangedVariablesInSemanticNode(node);
// System.out.println(" UNCHANGED = " + unchangedVariables.toString()); // System.out.println(" UNCHANGED = " + unchangedVariables.toString());
separateGuardsAndBeforeAfterPredicates(node); separateGuardsAndBeforeAfterPredicates(node);
findAssignments(); findAssignments(variableDecls);
} }
public AOperation getBOperation(BAstCreator bASTCreator) { public AOperation getBOperation(BAstCreator bASTCreator) {
bASTCreator.setUnchangedVariablesNames(unchangedVariables); bASTCreator.setUnchangedVariablesNames(this.getUnchangedVariables());
List<PPredicate> whereList = new ArrayList<>(); List<PPredicate> whereList = new ArrayList<>();
for (OpApplNode o : this.getExistQuans()) { for (OpApplNode o : this.getExistQuans()) {
whereList.add(bASTCreator.visitBoundsOfLocalVariables(o)); whereList.add(bASTCreator.visitBoundsOfLocalVariables(o));
} }
for (ExprOrOpArgNode g : guards) { for (ExprOrOpArgNode g : guards) {
whereList.add(bASTCreator.visitExprOrOpArgNodePredicate(g)); whereList.add(bASTCreator.visitExprOrOpArgNodePredicate(g));
} }
List<PExpression> leftSideOfAssigment = new ArrayList<>(); List<PExpression> lhsAssignment = new ArrayList<>();
List<PExpression> rightSideOfAssigment = new ArrayList<>(); List<PExpression> rhsAssignment = new ArrayList<>();
for (Entry<SymbolNode, ExprOrOpArgNode> entry : assignments.entrySet()) { assignments.forEach((id, assignExpr) -> {
leftSideOfAssigment.add(bASTCreator.createIdentifierNode(entry.getKey())); lhsAssignment.add(bASTCreator.createIdentifierNode(id));
rightSideOfAssigment.add(bASTCreator.visitExprOrOpArgNodeExpression(entry.getValue())); rhsAssignment.add(bASTCreator.visitExprOrOpArgNodeExpression(assignExpr));
} });
PSubstitution operationBody; PSubstitution operationBody;
AAssignSubstitution assign = new AAssignSubstitution(); AAssignSubstitution assign = new AAssignSubstitution();
if (!anyVariables.isEmpty()) { // ANY x_n WHERE P THEN A END if (!anyVariables.isEmpty()) { // ANY x_n WHERE P THEN A END
List<PExpression> anyParams = new ArrayList<>(); List<PExpression> anyParams = new ArrayList<>();
for (OpDeclNode var : anyVariables) { for (OpDeclNode var : anyVariables) {
String nextName = var.getName().toString() + "_n"; AIdentifierExpression nextName = createIdentifier(var.getName().toString() + "_n");
anyParams.add(BAstCreator.createIdentifierNode(nextName)); anyParams.add(nextName);
whereList.add(new AMemberPredicate(nextName.clone(), TypeChecker.getType(var).getBNode()));
whereList.add(new AMemberPredicate( lhsAssignment.add(bASTCreator.createIdentifierNode(var));
BAstCreator.createIdentifierNode(nextName), rhsAssignment.add(nextName.clone());
((TLAType) var.getToolObject(TYPE_ID)).getBNode()
));
leftSideOfAssigment.add(bASTCreator.createIdentifierNode(var));
rightSideOfAssigment.add(BAstCreator.createIdentifierNode(nextName));
} }
whereList.addAll(createBeforeAfterPredicates(bASTCreator)); whereList.addAll(createBeforeAfterPredicates(bASTCreator));
operationBody = new AAnySubstitution(anyParams, bASTCreator.createConjunction(whereList), assign); operationBody = new AAnySubstitution(anyParams, createConjunction(whereList), assign);
} else if (!whereList.isEmpty()) { // SELECT P THEN A END } else if (!whereList.isEmpty()) { // SELECT P THEN A END
whereList.addAll(createBeforeAfterPredicates(bASTCreator)); whereList.addAll(createBeforeAfterPredicates(bASTCreator));
for (ExprOrOpArgNode e : beforeAfterPredicates) { for (ExprOrOpArgNode e : beforeAfterPredicates) {
whereList.add(bASTCreator.visitExprOrOpArgNodePredicate(e)); whereList.add(bASTCreator.visitExprOrOpArgNodePredicate(e));
} }
operationBody = new ASelectSubstitution(bASTCreator.createConjunction(whereList), assign, new ArrayList<>(), null); operationBody = new ASelectSubstitution(createConjunction(whereList), assign, new ArrayList<>(), null);
} else { // BEGIN A END } else { // BEGIN A END
operationBody = new ABlockSubstitution(assign); operationBody = new ABlockSubstitution(assign);
} }
if (!leftSideOfAssigment.isEmpty()) { if (!lhsAssignment.isEmpty()) {
assign.setLhsExpression(leftSideOfAssigment); assign.setLhsExpression(lhsAssignment);
assign.setRhsExpressions(rightSideOfAssigment); assign.setRhsExpressions(rhsAssignment);
} else { // skip } else { // skip
assign.replaceBy(new ASkipSubstitution()); assign.replaceBy(new ASkipSubstitution());
} }
return new AOperation( return new AOperation(new LinkedList<>(),
new ArrayList<>(),
bASTCreator.createPositionedTIdentifierLiteral(name, getNode()), bASTCreator.createPositionedTIdentifierLiteral(name, getNode()),
this.getFormalParams().stream().map(bASTCreator::createIdentifierNode).collect(Collectors.toList()), this.getFormalParams().stream().map(bASTCreator::createIdentifierNode).collect(Collectors.toList()),
operationBody operationBody
); );
} }
private ArrayList<PPredicate> createBeforeAfterPredicates(BAstCreator bAstCreator) { private List<PPredicate> createBeforeAfterPredicates(BAstCreator bAstCreator) {
ArrayList<PPredicate> predicates = new ArrayList<>(); List<PPredicate> predicates = new ArrayList<>();
for (ExprOrOpArgNode e : beforeAfterPredicates) { for (ExprOrOpArgNode e : beforeAfterPredicates) {
PPredicate body = null; PPredicate body = null;
if (e instanceof OpApplNode) { if (e instanceof OpApplNode) {
...@@ -114,8 +110,7 @@ public class BOperation extends BuiltInOPs implements TranslationGlobals { ...@@ -114,8 +110,7 @@ public class BOperation extends BuiltInOPs implements TranslationGlobals {
OpDefNode def = (OpDefNode) opApplNode.getOperator(); OpDefNode def = (OpDefNode) opApplNode.getOperator();
FormalParamNode[] params = def.getParams(); FormalParamNode[] params = def.getParams();
for (int j = 0; j < params.length; j++) { for (int j = 0; j < params.length; j++) {
FormalParamNode param = params[j]; params[j].setToolObject(SUBSTITUTE_PARAM, opApplNode.getArgs()[j]);
param.setToolObject(SUBSTITUTE_PARAM, opApplNode.getArgs()[j]);
} }
body = bAstCreator.visitExprNodePredicate(def.getBody()); body = bAstCreator.visitExprNodePredicate(def.getBody());
} }
...@@ -128,26 +123,24 @@ public class BOperation extends BuiltInOPs implements TranslationGlobals { ...@@ -128,26 +123,24 @@ public class BOperation extends BuiltInOPs implements TranslationGlobals {
return predicates; return predicates;
} }
private void findAssignments() { private void findAssignments(OpDeclNode[] variableDecls) {
PrimedVariablesFinder primedVariablesFinder = new PrimedVariablesFinder(beforeAfterPredicates); PrimedVariablesFinder primedVariablesFinder = new PrimedVariablesFinder(beforeAfterPredicates);
for (ExprOrOpArgNode node : new ArrayList<>(beforeAfterPredicates)) { for (ExprOrOpArgNode node : new ArrayList<>(beforeAfterPredicates)) {
if (node instanceof OpApplNode) { if (node instanceof OpApplNode) {
OpApplNode opApplNode = (OpApplNode) node; OpApplNode opApplNode = (OpApplNode) node;
if (opApplNode.getOperator().getKind() == BuiltInKind) { if (opApplNode.getOperator().getKind() == BuiltInKind
&& getOpCode(opApplNode.getOperator().getName()) == OPCODE_eq) {
if (OPCODE_eq == getOpCode(opApplNode.getOperator().getName())) {
ExprOrOpArgNode arg1 = opApplNode.getArgs()[0]; // we have equality arg1 = RHS ExprOrOpArgNode arg1 = opApplNode.getArgs()[0]; // we have equality arg1 = RHS
try { try {
OpApplNode arg11 = (OpApplNode) arg1; OpApplNode primeAppl = (OpApplNode) arg1;
if (getOpCode(arg11.getOperator().getName()) == OPCODE_prime) { if (getOpCode(primeAppl.getOperator().getName()) == OPCODE_prime) {
OpApplNode v = (OpApplNode) arg11.getArgs()[0]; OpDeclNode var = (OpDeclNode) ((OpApplNode) primeAppl.getArgs()[0]).getOperator(); // var is first arg of prime
SymbolNode var = v.getOperator();
// we have equality var' = RHS // we have equality var' = RHS
if (!primedVariablesFinder.getTwiceUsedVariables().contains(var)) { if (!primedVariablesFinder.getTwiceUsedVariables().contains(var)) {
// var' is only used once in all before after predicates // var' is only used once in all before after predicates
// meaning we do not need it as parameter of the ANY // meaning we do not need it as parameter of the ANY
// and can add an assignment var := RHS // and can add an assignment var := RHS
assignments.put(v.getOperator(), opApplNode.getArgs()[1]); // RHS of assignment assignments.put(var, opApplNode.getArgs()[1]); // RHS of assignment
beforeAfterPredicates.remove(node); beforeAfterPredicates.remove(node);
// System.out.println("Detected assignment " + var.getName().toString() + "' = <RHS>"); // System.out.println("Detected assignment " + var.getName().toString() + "' = <RHS>");
} }
...@@ -155,18 +148,16 @@ public class BOperation extends BuiltInOPs implements TranslationGlobals { ...@@ -155,18 +148,16 @@ public class BOperation extends BuiltInOPs implements TranslationGlobals {
} catch (ClassCastException e) { } catch (ClassCastException e) {
} }
} }
}
} }
} }
anyVariables = new ArrayList<>(); anyVariables.clear();
Collections.addAll(anyVariables, specAnalyser.getModuleNode().getVariableDecls()); Collections.addAll(anyVariables, variableDecls);
// for (SymbolNode symbol : primedVariablesFinder.getAllVariables()) { // for (SymbolNode symbol : primedVariablesFinder.getAllVariables()) {
// anyVariables.add((OpDeclNode) symbol); // anyVariables.add((OpDeclNode) symbol);
// } // }
anyVariables.removeAll(assignments.keySet()); anyVariables.removeAll(assignments.keySet());
anyVariables.removeAll(unchangedVariablesList); anyVariables.removeAll(unchangedVariables);
} }
private void separateGuardsAndBeforeAfterPredicates(ExprOrOpArgNode node) { private void separateGuardsAndBeforeAfterPredicates(ExprOrOpArgNode node) {
...@@ -174,132 +165,48 @@ public class BOperation extends BuiltInOPs implements TranslationGlobals { ...@@ -174,132 +165,48 @@ public class BOperation extends BuiltInOPs implements TranslationGlobals {
OpApplNode opApplNode = (OpApplNode) node; OpApplNode opApplNode = (OpApplNode) node;
if (opApplNode.getOperator().getKind() == BuiltInKind) { if (opApplNode.getOperator().getKind() == BuiltInKind) {
switch (getOpCode(opApplNode.getOperator().getName())) { switch (getOpCode(opApplNode.getOperator().getName())) {
case OPCODE_land: // \land case OPCODE_land: // \land (getArgs has 2 args)
{
separateGuardsAndBeforeAfterPredicates(opApplNode.getArgs()[0]);
separateGuardsAndBeforeAfterPredicates(opApplNode.getArgs()[1]);
return;
}
case OPCODE_cl: // $ConjList case OPCODE_cl: // $ConjList
{ Arrays.stream(opApplNode.getArgs()).forEach(this::separateGuardsAndBeforeAfterPredicates);
for (int i = 0; i < opApplNode.getArgs().length; i++) {
separateGuardsAndBeforeAfterPredicates(opApplNode
.getArgs()[i]);
}
return; return;
} default:
default: { (opApplNode.level < 2 ? guards : beforeAfterPredicates).add(node);
if (opApplNode.level < 2) { // guards: should we check if nonLeibnizParams is empty?
guards.add(node); // should we be checking nonLeibnizParams is empty ?
} else {
beforeAfterPredicates.add(node);
}
return; return;
} }
}
}
}
if (node.level < 2) {
guards.add(node);
} else {
beforeAfterPredicates.add(node);
}
// beforeAfterPredicates.add(node);
}
private void evalParams() {
opParams = new ArrayList<>();
formalParams = new ArrayList<>();
for (OpApplNode n : existQuans) {
FormalParamNode[][] params = n.getBdedQuantSymbolLists();
for (FormalParamNode[] param : params) {
for (FormalParamNode formalParamNode : param) {
formalParams.add(formalParamNode);
opParams.add(formalParamNode.getName().toString());
}
}
}
}
public SymbolNode getSymbolNode() {
if (node != null && node.getOperator().getKind() == UserDefinedOpKind) {
return node.getOperator();
}
return null;
}
public String getName() {
return name;
}
public ExprNode getNode() {
return node;
}
public List<OpApplNode> getExistQuans() {
return new ArrayList<>(existQuans);
}
public List<String> getOpParams() {
return opParams;
} }
public List<FormalParamNode> getFormalParams() {
return formalParams;
} }
(node.level < 2 ? guards : beforeAfterPredicates).add(node); // level = 2 means action predicate
public List<String> getUnchangedVariables() {
return unchangedVariables;
}
private void findUnchangedVariables() {
unchangedVariables = new ArrayList<>();
findUnchangedVariablesInSemanticNode(node);
} }
private void findUnchangedVariablesInSemanticNode(SemanticNode node) { private void findUnchangedVariablesInSemanticNode(SemanticNode node) {
switch (node.getKind()) { switch (node.getKind()) {
case OpApplKind: { case OpApplKind:
findUnchangedVariablesInOpApplNode((OpApplNode) node); findUnchangedVariablesInOpApplNode((OpApplNode) node);
return; return;
} case LetInKind:
case LetInKind: { findUnchangedVariablesInSemanticNode(((LetInNode) node).getBody());
LetInNode letNode = (LetInNode) node;
findUnchangedVariablesInSemanticNode(letNode.getBody());
return; return;
} case SubstInKind:
findUnchangedVariablesInSemanticNode(((SubstInNode) node).getBody());
case SubstInKind: {
SubstInNode substInNode = (SubstInNode) node;
findUnchangedVariablesInSemanticNode(substInNode.getBody());
}
} }
} }
private void findUnchangedVariablesInOpApplNode(OpApplNode n) { private void findUnchangedVariablesInOpApplNode(OpApplNode n) {
int kind = n.getOperator().getKind(); int kind = n.getOperator().getKind();
if (kind == UserDefinedOpKind && !BBuiltInOPs.contains(n.getOperator().getName())) { if (kind == UserDefinedOpKind && !BBuiltInOPs.contains(n.getOperator().getName())) {
OpDefNode def = (OpDefNode) n.getOperator(); findUnchangedVariablesInSemanticNode(((OpDefNode) n.getOperator()).getBody());
findUnchangedVariablesInSemanticNode(def.getBody());
} else if (kind == BuiltInKind) { } else if (kind == BuiltInKind) {
int opcode = BuiltInOPs.getOpCode(n.getOperator().getName()); switch (BuiltInOPs.getOpCode(n.getOperator().getName())) {
switch (opcode) {
case OPCODE_land: // \land case OPCODE_land: // \land
case OPCODE_cl: { // $ConjList case OPCODE_cl: // $ConjList
for (int i = 0; i < n.getArgs().length; i++) { Arrays.stream(n.getArgs()).forEach(this::findUnchangedVariablesInSemanticNode);
findUnchangedVariablesInSemanticNode(n.getArgs()[i]);
}
return; return;
}
case OPCODE_unchanged: { case OPCODE_unchanged: {
n.setToolObject(USED, false); // n.setToolObject(USED, false); FIXME: this tool object is never used?
OpApplNode k = (OpApplNode) n.getArgs()[0]; OpApplNode k = (OpApplNode) n.getArgs()[0];
if (k.getOperator().getKind() == VariableDeclKind) { if (k.getOperator().getKind() == VariableDeclKind) {
unchangedVariablesList.add((OpDeclNode) k.getOperator()); unchangedVariables.add((OpDeclNode) k.getOperator());
String name = k.getOperator().getName().toString();
unchangedVariables.add(name);
} else { } else {
// Tuple // Tuple
for (int i = 0; i < k.getArgs().length; i++) { for (int i = 0; i < k.getArgs().length; i++) {
...@@ -310,7 +217,7 @@ public class BOperation extends BuiltInOPs implements TranslationGlobals { ...@@ -310,7 +217,7 @@ public class BOperation extends BuiltInOPs implements TranslationGlobals {
// we have a definition // we have a definition
OpDefNode def = (OpDefNode) var.getOperator(); OpDefNode def = (OpDefNode) var.getOperator();
if (def.getParams().length > 0) { if (def.getParams().length > 0) {
// we do not support definitions with arguments yet // TODO: we do not support definitions with arguments yet
throw new RuntimeException("Declaration with parameters not supported for UNCHANGED: " + var.getOperator().getName() + " " + var.getLocation()); throw new RuntimeException("Declaration with parameters not supported for UNCHANGED: " + var.getOperator().getName() + " " + var.getLocation());
} }
ExprNode body = def.getBody(); ExprNode body = def.getBody();
...@@ -323,15 +230,44 @@ public class BOperation extends BuiltInOPs implements TranslationGlobals { ...@@ -323,15 +230,44 @@ public class BOperation extends BuiltInOPs implements TranslationGlobals {
} else if (!(var.getOperator() instanceof OpDeclNode)) { } else if (!(var.getOperator() instanceof OpDeclNode)) {
throw new RuntimeException("Cannot convert to list of UNCHANGED variables: " + var.getOperator().getName() + " " + var.getLocation()); throw new RuntimeException("Cannot convert to list of UNCHANGED variables: " + var.getOperator().getName() + " " + var.getLocation());
} else { } else {
unchangedVariablesList.add((OpDeclNode) var.getOperator()); unchangedVariables.add((OpDeclNode) var.getOperator());
String name = var.getOperator().getName().toString(); }
unchangedVariables.add(name);
} }
} }
} }
} }
} }
} }
public SymbolNode getSymbolNode() {
if (node != null && node.getOperator().getKind() == UserDefinedOpKind) {
return node.getOperator();
}
return null;
}
public String getName() {
return name;
}
public ExprNode getNode() {
return node;
}
public List<OpApplNode> getExistQuans() {
return new ArrayList<>(existQuans);
}
public List<String> getOpParams() {
return formalParams.stream().map(f -> f.getName().toString()).collect(Collectors.toList());
}
public List<FormalParamNode> getFormalParams() {
return formalParams;
}
public List<String> getUnchangedVariables() {
return unchangedVariables.stream().map(u -> u.getName().toString()).collect(Collectors.toList());
} }
} }
......
...@@ -22,6 +22,7 @@ public class OperationsFinder extends AbstractASTVisitor { ...@@ -22,6 +22,7 @@ public class OperationsFinder extends AbstractASTVisitor {
private List<OpApplNode> exists; private List<OpApplNode> exists;
// a list containing all existential quantifier which will be parameters in the resulting B Machine // a list containing all existential quantifier which will be parameters in the resulting B Machine
private final List<BOperation> bOperations; private final List<BOperation> bOperations;
private final List<String> generatedOperations = new ArrayList<>();
public OperationsFinder(SpecAnalyser specAnalyser) { public OperationsFinder(SpecAnalyser specAnalyser) {
this.specAnalyser = specAnalyser; this.specAnalyser = specAnalyser;
...@@ -55,7 +56,7 @@ public class OperationsFinder extends AbstractASTVisitor { ...@@ -55,7 +56,7 @@ public class OperationsFinder extends AbstractASTVisitor {
public void visitUserDefinedNode(OpApplNode n) { public void visitUserDefinedNode(OpApplNode n) {
OpDefNode def = (OpDefNode) n.getOperator(); OpDefNode def = (OpDefNode) n.getOperator();
if (BBuiltInOPs.contains(def.getName())) { if (BBuiltInOPs.contains(def.getName())) {
bOperations.add(new BOperation(def.getName().toString(), n, exists, specAnalyser)); addOperation(def.getName().toString(), n, exists, specAnalyser);
return; return;
} }
...@@ -73,32 +74,18 @@ public class OperationsFinder extends AbstractASTVisitor { ...@@ -73,32 +74,18 @@ public class OperationsFinder extends AbstractASTVisitor {
int opcode = BuiltInOPs.getOpCode(opname); int opcode = BuiltInOPs.getOpCode(opname);
DebugUtils.printDebugMsg("OPCODE of " + opname + " = "+ opcode); DebugUtils.printDebugMsg("OPCODE of " + opname + " = "+ opcode);
switch (opcode) { switch (opcode) {
case OPCODE_dl: { // DisjList: split action further case OPCODE_dl: // DisjList: split action further
if (n.getArgs().length == 1) { if (n.getArgs().length == 1) {
visitExprOrOpArgNode(n.getArgs()[0]); visitExprOrOpArgNode(n.getArgs()[0]);
} else { } else {
String oldName = currentName; visitArgs(n);
List<OpApplNode> oldExists = new ArrayList<>(exists);
for (int i = 0; i < n.getArgs().length; i++) {
exists = new ArrayList<>(oldExists);
currentName = oldName + i;
visitExprOrOpArgNode(n.getArgs()[i]);
}
} }
return; return;
}
case OPCODE_lor: { // logical or: split action further
String oldName = currentName;
List<OpApplNode> oldExists = new ArrayList<>(exists);
for (int i = 0; i < n.getArgs().length; i++) { case OPCODE_lor: // logical or: split action further
exists = new ArrayList<>(oldExists); visitArgs(n);
currentName = oldName + i;
visitExprOrOpArgNode(n.getArgs()[i]);
}
return; return;
}
case OPCODE_be: { // BoundedExists case OPCODE_be: { // BoundedExists
exists.add(n); exists.add(n);
visitExprOrOpArgNode(n.getArgs()[0]); visitExprOrOpArgNode(n.getArgs()[0]);
...@@ -119,24 +106,45 @@ public class OperationsFinder extends AbstractASTVisitor { ...@@ -119,24 +106,45 @@ public class OperationsFinder extends AbstractASTVisitor {
case OPCODE_in: // \in case OPCODE_in: // \in
case OPCODE_notin: // \notin case OPCODE_notin: // \notin
case OPCODE_subseteq: // \subseteq - subset or equal case OPCODE_subseteq: // \subseteq - subset or equal
case OPCODE_fa: // $FcnApply f[1] case OPCODE_fa: // $FcnApply f[1] FIXME: how can FcnApply be an action?
case OPCODE_ite: // IF THEN ELSE case OPCODE_ite: // IF THEN ELSE
case OPCODE_case: { case OPCODE_case: // CASE p1 -> e1 [] p2 -> e2
// TODO case OPCODE_aa: // <<A>>_e
// TODO case OPCODE_sa: // [A]_e
// no further decomposing: create a B operation // no further decomposing: create a B operation
bOperations.add(new BOperation(currentName, n, exists, specAnalyser)); addOperation(currentName, n, exists, specAnalyser);
return; return;
} }
}
//System.out.println("OPCODE of " + opname + " = "+ opcode);
if (opname == BBuildIns.OP_false || opname == BBuildIns.OP_true) { if (opname == BBuildIns.OP_false || opname == BBuildIns.OP_true) {
// FALSE: always disabled; TRUE: CHAOS // FALSE: always disabled; TRUE: CHAOS
bOperations.add(new BOperation(currentName, n, exists, specAnalyser)); addOperation(currentName, n, exists, specAnalyser);
return; return;
} }
throw new RuntimeException(String.format("Expected an action at '%s':%n%s", opname, n.getLocation())); throw new RuntimeException(String.format("Expected an action at '%s':%n%s", opname, n.getLocation()));
} }
private void visitArgs(OpApplNode n) {
String oldName = currentName;
List<OpApplNode> oldExists = new ArrayList<>(exists);
for (int i = 0; i < n.getArgs().length; i++) {
exists = new ArrayList<>(oldExists);
currentName = oldName + i;
visitExprOrOpArgNode(n.getArgs()[i]);
}
}
private void addOperation(String name, OpApplNode node, List<OpApplNode> exists, SpecAnalyser specAnalyser) {
if (!generatedOperations.contains(name)) {
bOperations.add(new BOperation(name, node, exists, specAnalyser));
generatedOperations.add(name);
return;
}
DebugUtils.printMsg("Duplicate operation not translated: " + name);
// TODO: handle fixed parameters of an action definition, e.g. Act1(2) /\ Act1(2)
}
public List<BOperation> getBOperations() { public List<BOperation> getBOperations() {
return bOperations; return bOperations;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment