From b2d240f81613e02d90192555127b26aab5ae964e Mon Sep 17 00:00:00 2001 From: Chris Myers Date: Wed, 5 Jul 2017 16:13:44 -0600 Subject: [PATCH] Move verification back into iBioSim. Update the scripts Update version to 3.0.0-SNAPSHOT --- analysis/pom.xml | 5 +- bin/iBioSim.bat | 4 +- bin/iBioSim.linux64 | 10 +- conversion/pom.xml | 4 +- dataModels/pom.xml | 2 +- gui/pom.xml | 12 +- learn/pom.xml | 4 +- pom.xml | 3 +- synthesis/pom.xml | 5 +- verification/.gitignore | 1 + verification/pom.xml | 21 + .../verification/FileExtentionFilter.java | 39 + .../verification/VerificationCommandLine.java | 173 + .../lema/verification/lpn/Abstraction.java | 3599 +++++++++ .../async/lema/verification/lpn/ExprTree.java | 5678 ++++++++++++++ .../lema/verification/lpn/JavaCharStream.java | 626 ++ .../ece/async/lema/verification/lpn/LPN.java | 3209 ++++++++ .../lema/verification/lpn/Lpn2verilog.java | 665 ++ .../lpn/LpnDecomposition/Component.java | 159 + .../lpn/LpnDecomposition/Edge.java | 40 + .../LpnDecomposition/LpnComponentGraph.java | 145 + .../LpnDecomposition/LpnComponentList.java | 271 + .../lpn/LpnDecomposition/LpnProcess.java | 382 + .../lpn/LpnDecomposition/Vertex.java | 105 + .../LpnDecomposition/VertexComparator.java | 41 + .../lema/verification/lpn/ParseException.java | 205 + .../async/lema/verification/lpn/Parser.java | 1467 ++++ .../ece/async/lema/verification/lpn/Parser.jj | 449 ++ .../verification/lpn/ParserConstants.java | 375 + .../verification/lpn/ParserTokenManager.java | 3726 +++++++++ .../async/lema/verification/lpn/Place.java | 121 + .../async/lema/verification/lpn/Token.java | 149 + .../lema/verification/lpn/TokenMgrError.java | 167 + .../lema/verification/lpn/Transition.java | 1034 +++ .../lema/verification/lpn/Translator.java | 1906 +++++ .../async/lema/verification/lpn/Variable.java | 201 + .../lpn/properties/AbstractionProperty.java | 136 + .../lpn/properties/BuildProperty.java | 1103 +++ .../verification/lpn/properties/Property.g | 396 + .../lpn/properties/PropertyLexer.java | 2505 ++++++ .../lpn/properties/PropertyParser.java | 4057 ++++++++++ .../platu/BinaryTree/BinaryTree.java | 314 + .../verification/platu/BinaryTree/Node.java | 180 + .../lema/verification/platu/MDD/MDT.java | 83 + .../lema/verification/platu/MDD/Mdd.java | 183 + .../lema/verification/platu/MDD/mddNode.java | 824 ++ .../lema/verification/platu/MDD/mdtNode.java | 174 + .../platu/TimingAnalysis/DBM.java | 223 + .../platu/TimingAnalysis/Poset.java | 257 + .../platu/TimingAnalysis/PrjStateZone.java | 69 + .../platu/TimingAnalysis/TimingAnalysis.java | 791 ++ .../platu/TimingAnalysis/TimingState.java | 88 + .../platu/TimingAnalysis/Zone1.java | 632 ++ .../platu/TimingAnalysis/mdtNode.java | 161 + .../platu/common/BinTreeTable.java | 59 + .../verification/platu/common/Common.java | 159 + .../verification/platu/common/HashTable.java | 54 + .../platu/common/IndexObjMap.java | 79 + .../platu/common/IntArrayObj.java | 93 + .../verification/platu/common/MddTable.java | 208 + .../lema/verification/platu/common/Pair.java | 78 + .../verification/platu/common/PlatuObj.java | 33 + .../platu/common/SetIntTuple.java | 33 + .../platu/expression/AddNode.java | 56 + .../platu/expression/AndNode.java | 59 + .../platu/expression/ArrayElement.java | 87 + .../platu/expression/ArrayNode.java | 161 + .../platu/expression/BitAndNode.java | 56 + .../platu/expression/BitNegNode.java | 53 + .../platu/expression/BitOrNode.java | 56 + .../platu/expression/BitXorNode.java | 56 + .../platu/expression/ConstNode.java | 55 + .../platu/expression/DivNode.java | 56 + .../platu/expression/EquivNode.java | 59 + .../platu/expression/Expression.java | 74 + .../platu/expression/ExpressionNode.java | 43 + .../platu/expression/GreatEqualNode.java | 59 + .../platu/expression/GreatNode.java | 59 + .../platu/expression/ImplicationNode.java | 59 + .../platu/expression/LeftShiftNode.java | 56 + .../platu/expression/LessEqualNode.java | 59 + .../platu/expression/LessNode.java | 59 + .../platu/expression/MinNode.java | 53 + .../platu/expression/ModNode.java | 56 + .../platu/expression/MultNode.java | 56 + .../platu/expression/NegNode.java | 56 + .../platu/expression/NotEquivNode.java | 59 + .../verification/platu/expression/OrNode.java | 59 + .../platu/expression/RightShiftNode.java | 56 + .../platu/expression/SubNode.java | 56 + .../platu/expression/TernaryNode.java | 61 + .../platu/expression/VarNode.java | 114 + .../platu/logicAnalysis/Analysis.java | 5502 +++++++++++++ .../platu/logicAnalysis/CompositeState.java | 200 + .../logicAnalysis/CompositeStateGraph.java | 330 + .../logicAnalysis/CompositeStateTran.java | 115 + .../logicAnalysis/CompositionalAnalysis.java | 2963 +++++++ .../logicAnalysis/CompositionalThread.java | 208 + .../platu/logicAnalysis/Constraint.java | 169 + .../platu/logicAnalysis/HashSetWrapper.java | 55 + .../platu/logicAnalysis/LpnState.java | 132 + .../platu/logicAnalysis/PrjLpnState.java | 72 + .../logicAnalysis/StateSetInterface.java | 34 + .../verification/platu/main/Interpretor.java | 233 + .../lema/verification/platu/main/Main.java | 377 + .../lema/verification/platu/main/Options.java | 523 ++ .../markovianAnalysis/MarkovianAnalysis.java | 1177 +++ .../PerfromTransientMarkovAnalysisThread.java | 67 + .../markovianAnalysis/ProbGlobalState.java | 288 + .../markovianAnalysis/ProbGlobalStateSet.java | 77 + .../markovianAnalysis/ProbLocalState.java | 79 + .../ProbLocalStateGraph.java | 505 ++ .../platu/markovianAnalysis/Property.java | 51 + .../TransientMarkovMatrixMultiplyThread.java | 50 + .../platu/partialOrders/DependentSet.java | 63 + .../partialOrders/DependentSetComparator.java | 93 + .../ProbStaticDependencySets.java | 156 + .../partialOrders/StaticDependencySets.java | 553 ++ .../platu/platuLpn/DualHashMap.java | 99 + .../verification/platu/platuLpn/LPNTran.java | 819 ++ .../platu/platuLpn/LPNTranRelation.java | 204 + .../platu/platuLpn/LpnTranList.java | 120 + .../verification/platu/platuLpn/PlatuLPN.java | 950 +++ .../verification/platu/platuLpn/VarExpr.java | 83 + .../platu/platuLpn/VarExprList.java | 136 + .../verification/platu/platuLpn/VarSet.java | 55 + .../verification/platu/platuLpn/VarType.java | 26 + .../verification/platu/platuLpn/VarVal.java | 87 + .../platu/platuLpn/VarValSet.java | 179 + .../platu/platuLpn/io/Instance.java | 47 + .../platu/platuLpn/io/PlatuGrammar.g | 1407 ++++ .../platu/platuLpn/io/PlatuGrammar.tokens | 104 + .../platu/platuLpn/io/PlatuGrammarLexer.java | 2514 ++++++ .../platu/platuLpn/io/PlatuGrammarParser.java | 5134 ++++++++++++ .../platu/platuLpn/io/PlatuInst.g | 1501 ++++ .../platu/platuLpn/io/PlatuInstLexer.java | 3258 ++++++++ .../platu/platuLpn/io/PlatuInstParser.java | 5581 +++++++++++++ .../platu/platuLpn/io/WriteLPN.java | 180 + .../verification/platu/por1/AmpleSet.java | 363 + .../verification/platu/por1/AmpleSubset.java | 538 ++ .../platu/por1/SearchDepFromLPN.java | 377 + .../platu/por1/SearchDepFromState.java | 275 + .../platu/project/DesignUnit.java | 125 + .../platu/project/IDGenerator.java | 73 + .../platu/project/PrintStackTrace.java | 43 + .../verification/platu/project/PrjState.java | 251 + .../verification/platu/project/Project.java | 587 ++ .../platu/project/prjStateTimed.java | 71 + .../verification/platu/stategraph/State.java | 592 ++ .../platu/stategraph/StateGraph.java | 2307 ++++++ .../platu/stategraph/StateTran.java | 93 + .../platu/stategraph/UpdateTimer.java | 106 + .../archive/Interval.java | 187 + .../archive/OctMember.java | 103 + .../archive/PreContinuous.java | 26 + .../archive/RateNonZero.java | 46 + .../archive/RateZero.java | 31 + .../archive/Timer.java | 51 + .../timed_state_exploration/dbm2/DBMLL.java | 708 ++ .../timed_state_exploration/dbm2/IDBM.java | 26 + .../dbm2/LPNState.java | 555 ++ .../dbm2/LPNTransitionState.java | 313 + .../dbm2/LPNTranslator.java | 542 ++ .../timed_state_exploration/dbm2/README.txt | 5 + .../dbm2/StateExploration.java | 370 + .../octagon/Equivalence.java | 109 + .../octagon/Octagon.java | 5528 +++++++++++++ .../zone/Analysis_Timed.java | 382 + .../zone/Project_Timed.java | 215 + .../zone/StateGraph_timed.java | 173 + .../zone/TestZoneFiles.txt | 40 + .../zone/TimedPrjState.java | 195 + .../zone/TimedState.java | 357 + .../zone/TimedStateSet.java | 694 ++ .../timed_state_exploration/zone/Zone.java | 1836 +++++ .../zone/ZoneGraph.java | 1184 +++ .../zone/ZoneGraphTest.java | 257 + .../zone/ZoneTest.java | 271 + .../zone/ZoneType.java | 213 + .../zoneProject/Conolse7_26_2012.java | 142 + .../zoneProject/ContinuousRecordSet.java | 59 + .../zoneProject/ContinuousUtilities.java | 952 +++ .../zoneProject/Event.java | 155 + .../zoneProject/EventSet.java | 663 ++ .../zoneProject/InequalityVariable.java | 772 ++ .../zoneProject/IntervalPair.java | 177 + .../zoneProject/LPNContAndRate.java | 123 + .../zoneProject/LPNContinuousPair.java | 152 + .../zoneProject/LPNTransitionPair.java | 319 + .../zoneProject/RangeAndPairing.java | 84 + .../zoneProject/StateSet.java | 628 ++ .../zoneProject/TimedPrjState.java | 458 ++ .../zoneProject/UpdateContinuous.java | 335 + .../zoneProject/VariableRangePair.java | 93 + .../zoneProject/Zone.java | 6890 +++++++++++++++++ 195 files changed, 108574 insertions(+), 25 deletions(-) create mode 100644 verification/.gitignore create mode 100644 verification/pom.xml create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/FileExtentionFilter.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/VerificationCommandLine.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Abstraction.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ExprTree.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/JavaCharStream.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LPN.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Lpn2verilog.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/Component.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/Edge.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/LpnComponentGraph.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/LpnComponentList.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/LpnProcess.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/Vertex.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/VertexComparator.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ParseException.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Parser.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Parser.jj create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ParserConstants.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ParserTokenManager.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Place.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Token.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/TokenMgrError.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Transition.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Translator.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Variable.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/AbstractionProperty.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/BuildProperty.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/Property.g create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/PropertyLexer.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/PropertyParser.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/BinaryTree/BinaryTree.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/BinaryTree/Node.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/MDT.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/Mdd.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/mddNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/mdtNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/DBM.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/Poset.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/PrjStateZone.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/TimingAnalysis.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/TimingState.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/Zone1.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/mdtNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/BinTreeTable.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/Common.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/HashTable.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/IndexObjMap.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/IntArrayObj.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/MddTable.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/Pair.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/PlatuObj.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/SetIntTuple.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/AddNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/AndNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ArrayElement.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ArrayNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitAndNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitNegNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitOrNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitXorNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ConstNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/DivNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/EquivNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/Expression.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ExpressionNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/GreatEqualNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/GreatNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ImplicationNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/LeftShiftNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/LessEqualNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/LessNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/MinNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ModNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/MultNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/NegNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/NotEquivNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/OrNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/RightShiftNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/SubNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/TernaryNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/VarNode.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/Analysis.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositeState.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositeStateGraph.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositeStateTran.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositionalAnalysis.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositionalThread.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/Constraint.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/HashSetWrapper.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/LpnState.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/PrjLpnState.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/StateSetInterface.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/main/Interpretor.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/main/Main.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/main/Options.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/MarkovianAnalysis.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/PerfromTransientMarkovAnalysisThread.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbGlobalState.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbGlobalStateSet.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbLocalState.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbLocalStateGraph.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/Property.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/TransientMarkovMatrixMultiplyThread.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/DependentSet.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/DependentSetComparator.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/ProbStaticDependencySets.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/StaticDependencySets.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/DualHashMap.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/LPNTran.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/LPNTranRelation.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/LpnTranList.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/PlatuLPN.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarExpr.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarExprList.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarSet.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarType.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarVal.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarValSet.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/Instance.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuGrammar.g create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuGrammar.tokens create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuGrammarLexer.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuGrammarParser.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuInst.g create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuInstLexer.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuInstParser.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/WriteLPN.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/AmpleSet.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/AmpleSubset.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/SearchDepFromLPN.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/SearchDepFromState.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/DesignUnit.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/IDGenerator.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/PrintStackTrace.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/PrjState.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/Project.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/prjStateTimed.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/State.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/StateGraph.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/StateTran.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/UpdateTimer.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/Interval.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/OctMember.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/PreContinuous.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/RateNonZero.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/RateZero.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/Timer.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/DBMLL.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/IDBM.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/LPNState.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/LPNTransitionState.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/LPNTranslator.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/README.txt create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/StateExploration.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/octagon/Equivalence.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/octagon/Octagon.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/Analysis_Timed.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/Project_Timed.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/StateGraph_timed.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/TestZoneFiles.txt create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/TimedPrjState.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/TimedState.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/TimedStateSet.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/Zone.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneGraph.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneGraphTest.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneTest.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneType.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/Conolse7_26_2012.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/ContinuousRecordSet.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/ContinuousUtilities.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/Event.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/EventSet.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/InequalityVariable.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/IntervalPair.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/LPNContAndRate.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/LPNContinuousPair.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/LPNTransitionPair.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/RangeAndPairing.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/StateSet.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/TimedPrjState.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/UpdateContinuous.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/VariableRangePair.java create mode 100644 verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/Zone.java diff --git a/analysis/pom.xml b/analysis/pom.xml index 37aa76af7..ee5f01ce4 100644 --- a/analysis/pom.xml +++ b/analysis/pom.xml @@ -6,7 +6,7 @@ edu.utah.ece.async iBioSim - 0.0.1-SNAPSHOT + 3.0.0-SNAPSHOT ../ jar @@ -65,8 +65,7 @@ edu.utah.ece.async iBioSim-dataModels - 0.0.1-SNAPSHOT - compile + 3.0.0-SNAPSHOT diff --git a/bin/iBioSim.bat b/bin/iBioSim.bat index ffcfa2498..f29d02fcf 100755 --- a/bin/iBioSim.bat +++ b/bin/iBioSim.bat @@ -12,7 +12,5 @@ @rem @rem *************************************************************************** setlocal ENABLEDELAYEDEXPANSION -set CLASSPATH="%BIOSIM%\gui\dist\classes" -for /f %%a IN ('dir /b "%BIOSIM%\gui\lib\*.jar"') do call set CLASSPATH=!CLASSPATH!;"%BIOSIM%\gui\lib\%%a" -java -Xmx2048M -Xms2048M -XX:+UseSerialGC -classpath %CLASSPATH% main.Gui +java -Xmx2048M -Xms2048M -XX:+UseSerialGC -jar iBioSim.jar diff --git a/bin/iBioSim.linux64 b/bin/iBioSim.linux64 index 80b95977a..34cd4e4d0 100755 --- a/bin/iBioSim.linux64 +++ b/bin/iBioSim.linux64 @@ -8,7 +8,9 @@ fi if [ -z "$BIOSIM" ]; then export BIOSIM=$PWD/.. fi -export PATH=$BIOSIM/bin:$PATH -export LD_LIBRARY_PATH=$BIOSIM/lib64:$LD_LIBRARY_PATH -export DDLD_LIBRARY_PATH=$BIOSIM/lib64:$DDLD_LIBRARY_PATH -exec java -Xmx2048M -Xms2048M -XX:+UseSerialGC -jar iBioSim.jar +export PATH=$BIOSIM/bin:/usr/local/lib:$PATH + +export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH +export DDLD_LIBRARY_PATH=/usr/local/lib:$DDLD_LIBRARY_PATH + +exec java -Xmx2048M -Xms2048M -XX:+UseSerialGC -Djava.library.path=/usr/local/lib -jar iBioSim.jar diff --git a/conversion/pom.xml b/conversion/pom.xml index a2162457e..f133a2b21 100644 --- a/conversion/pom.xml +++ b/conversion/pom.xml @@ -6,7 +6,7 @@ edu.utah.ece.async iBioSim - 0.0.1-SNAPSHOT + 3.0.0-SNAPSHOT ../ jar @@ -120,7 +120,7 @@ edu.utah.ece.async iBioSim-dataModels - 0.0.1-SNAPSHOT + 3.0.0-SNAPSHOT uk.ac.ncl.ico2s diff --git a/dataModels/pom.xml b/dataModels/pom.xml index 1febfa204..ec7c05f80 100644 --- a/dataModels/pom.xml +++ b/dataModels/pom.xml @@ -6,7 +6,7 @@ edu.utah.ece.async iBioSim - 0.0.1-SNAPSHOT + 3.0.0-SNAPSHOT ../ jar diff --git a/gui/pom.xml b/gui/pom.xml index 078e36d3e..056cf5e1a 100644 --- a/gui/pom.xml +++ b/gui/pom.xml @@ -6,7 +6,7 @@ edu.utah.ece.async iBioSim - 0.0.1-SNAPSHOT + 3.0.0-SNAPSHOT ../ jar @@ -203,31 +203,31 @@ edu.utah.ece.async iBioSim-dataModels - 0.0.1-SNAPSHOT + 3.0.0-SNAPSHOT edu.utah.ece.async iBioSim-conversion - 0.0.1-SNAPSHOT + 3.0.0-SNAPSHOT edu.utah.ece.async iBioSim-learn - 0.0.1-SNAPSHOT + 3.0.0-SNAPSHOT edu.utah.ece.async iBioSim-analysis - 0.0.1-SNAPSHOT + 3.0.0-SNAPSHOT edu.utah.ece.async iBioSim-synthesis - 0.0.1-SNAPSHOT + 3.0.0-SNAPSHOT diff --git a/learn/pom.xml b/learn/pom.xml index ccee0133e..c3f66532f 100644 --- a/learn/pom.xml +++ b/learn/pom.xml @@ -5,7 +5,7 @@ iBioSim-learn edu.utah.ece.async - 0.0.1-SNAPSHOT + 3.0.0-SNAPSHOT ../ iBioSim @@ -15,7 +15,7 @@ edu.utah.ece.async iBioSim-analysis - 0.0.1-SNAPSHOT + 3.0.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 4100a06d9..f7e56a3b7 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 edu.utah.ece.async iBioSim - 0.0.1-SNAPSHOT + 3.0.0-SNAPSHOT pom iBioSim CAD tool aimed for the modeling, analysis, and design of genetic circuits. This tool supports both SBML and SBOL data models. @@ -36,6 +36,7 @@ gui synthesis learn + verification diff --git a/synthesis/pom.xml b/synthesis/pom.xml index a8e93abfb..b0db67e4f 100644 --- a/synthesis/pom.xml +++ b/synthesis/pom.xml @@ -6,7 +6,7 @@ edu.utah.ece.async iBioSim - 0.0.1-SNAPSHOT + 3.0.0-SNAPSHOT ../ jar @@ -14,8 +14,7 @@ edu.utah.ece.async iBioSim-dataModels - 0.0.1-SNAPSHOT - compile + 3.0.0-SNAPSHOT diff --git a/verification/.gitignore b/verification/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/verification/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/verification/pom.xml b/verification/pom.xml new file mode 100644 index 000000000..f85f51b1a --- /dev/null +++ b/verification/pom.xml @@ -0,0 +1,21 @@ + + + 4.0.0 + LEMA-verification + + edu.utah.ece.async + iBioSim + 3.0.0-SNAPSHOT + ../ + + jar + + + + edu.utah.ece.async + iBioSim-dataModels + 3.0.0-SNAPSHOT + + + diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/FileExtentionFilter.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/FileExtentionFilter.java new file mode 100644 index 000000000..b7dcba2c1 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/FileExtentionFilter.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification; + +import java.io.File; +import java.io.FileFilter; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class FileExtentionFilter implements FileFilter { + + private final String extension; + + FileExtentionFilter(String extenstion) { + this.extension = extenstion; + } + + @Override + public boolean accept(File pathname) { + return pathname.getPath().toLowerCase().endsWith(extension); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/VerificationCommandLine.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/VerificationCommandLine.java new file mode 100644 index 000000000..c04b1e17d --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/VerificationCommandLine.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification; + +import java.io.File; +import java.util.ArrayList; + +import javax.swing.JOptionPane; + +import edu.utah.ece.async.ibiosim.dataModels.util.GlobalConstants; +import edu.utah.ece.async.ibiosim.dataModels.util.exceptions.BioSimException; +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.project.Project; + +/** + * This class provides script to run depth-first search and partial order reduction (in the platu package) + * without the need for a GUI. + * + * @author Zhen Zhang + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class VerificationCommandLine { + + static String separator = GlobalConstants.separator; + + public static void main (String[] args) { + if (args.length == 0) { + System.err.println("Error: Missing arguments."); + System.exit(0); + } + String directory = null; + File dir = null; + ArrayList lpnList = new ArrayList(); + ArrayList lpnNames = new ArrayList(); + boolean allLPNs = false; + for (int i=0; i + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn; + + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import edu.utah.ece.async.ibiosim.dataModels.biomodel.util.Utility; +import edu.utah.ece.async.lema.verification.lpn.properties.AbstractionProperty; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Abstraction extends LPN { + + private HashMap process_trans = new HashMap(); + + private HashMap process_write = new HashMap(); + + private HashMap process_read = new HashMap(); + + /** + * A map from variable name to processes that write to the variable. + */ + private HashMap> processWriteToVar = new HashMap>(); + + /** + * A map from variable name to processes that read the variable. + */ + private HashMap> processReadVar = new HashMap>(); + + private ArrayList read = new ArrayList(); + + private ArrayList intVars; + + private ArrayList newestIntVars = new ArrayList(); + + final AbstractionProperty absProperty; + + public Abstraction(LPN lhpn) { + super(); + transitions = lhpn.transitions; + places = lhpn.places; + booleans = lhpn.booleans; + continuous = lhpn.continuous; + integers = lhpn.integers; + variables = lhpn.variables; + properties = lhpn.properties; + this.absProperty = new AbstractionProperty(); + } + + public Abstraction(LPN lhpn, AbstractionProperty absProperty) { + super(); + transitions = lhpn.transitions; + places = lhpn.places; + booleans = lhpn.booleans; + continuous = lhpn.continuous; + integers = lhpn.integers; + variables = lhpn.variables; + properties = lhpn.properties; + this.absProperty = absProperty; + } + + public void abstractSTG(boolean print) { + long start = System.nanoTime(); + boolean change = true; + for (Transition t : transitions.values()) { + if (t.getEnabling() == null) { + continue; + } + if (t.getEnabling().equals("") + || t.getEnabling().trim().equals("~shutdown") + || t.getEnabling().equals("~fail")) { + t.addEnabling(null); + } + } + Integer numTrans = transitions.size(); + Integer numPlaces = places.size(); + Integer numVars = variables.size(); + if (print) { + System.out.println("Transitions before abstraction: " + numTrans); + System.out.println("Places before abstraction: " + numPlaces); + System.out.println("Variables before abstraction: " + numVars); + } + boolean normalize = true; + if ((absProperty.preAbsModel.contains(absProperty.xform21) + || absProperty.loopAbsModel.contains(absProperty.xform21) || absProperty.postAbsModel + .contains(absProperty.xform21)) + && absProperty.getNormFactor() <= 0) { + message.setErrorDialog("Invalid Normalization Factor", "Normalization factor must be a non-negative integer.\nDelay normalization will not be performed."); + this.notifyObservers(this); + normalize = false; + } + Integer i = 0; + for (Object o : absProperty.preAbsModel.toArray()) { + String s = o.toString(); + if (s.equals(absProperty.xform12)) { + abstractAssign(); + } + divideProcesses(); + intVars = new ArrayList(); + for (String v : absProperty.getIntVars()) { + intVars.add(v); + } + // Transform 0 - Merge Parallel Places + if (s.equals(absProperty.xform0) && absProperty.isSimplify()) { + change = checkTrans0(change); + } + // Transform 1 - Remove a Place in a Self Loop + if (s.equals(absProperty.xform1) && absProperty.isSimplify()) { + change = checkTrans1(change); + } + // Transforms 5a, 6, 7 - Combine Transitions with the Same Preset + // and/or Postset + if ((s.equals(absProperty.xform5) || s.equals(absProperty.xform6) || s + .equals(absProperty.xform7)) + && absProperty.isAbstract()) { + change = checkTrans5(change); + } + // Transform 5b + if (s.equals(absProperty.xform5) && absProperty.isAbstract()) { + change = checkTrans5b(change); + } + // Transform 4 - Remove a Transition with a Single Place in the + // Preset + if (s.equals(absProperty.xform4) && absProperty.isSimplify()) { + change = checkTrans4(change); + } + // Transform 3 - Remove a Transition with a Single Place in the + // Postset + if (s.equals(absProperty.xform3) && absProperty.isSimplify()) { + change = checkTrans3(change); + } + // Transform 22 - Remove Vacuous Transitions (simplification) + if (s.equals(absProperty.xform22) && absProperty.isSimplify()) { + change = checkTrans22(change); + } + // Transform 23 - Remove Vacuous Transitions (abstraction) + if (s.equals(absProperty.xform22) && absProperty.isAbstract()) { + change = checkTrans23(change); + } + // Transform 14 - Remove Dead Places + if (s.equals(absProperty.xform14) && absProperty.isSimplify()) { + change = removeDeadPlaces(change); + } + // Transform 8 - Propagate local assignments + if (s.equals(absProperty.xform8) && absProperty.isSimplify()) { + change = checkTrans8(change); + } + // Transform 9 - Remove Write Before Write + if (s.equals(absProperty.xform9) && absProperty.isSimplify()) { + change = checkTrans9(change); + } + // Transform 10 - Simplify Expressions + if (s.equals(absProperty.xform10) && absProperty.isSimplify()) { + change = simplifyExpr(change); + } + // Transform 15 - Remove Dead Transitions + if (s.equals(absProperty.xform15) && absProperty.isSimplify()) { + change = removeDeadTransitions(change); + } + // Transform 17 - Remove Dominated Transitions + if (s.equals(absProperty.xform17) && absProperty.isSimplify()) { + change = removeDominatedTransitions(change); + change = removeRedundantTransitions(change); + } + // Transform 18 - Remove Unread Variables + if (s.equals(absProperty.xform18) && absProperty.isSimplify()) { + change = removeUnreadVars(change); + } + // Transform 20 - Remove Arc after Fail Transition + if (s.equals(absProperty.xform20) && absProperty.isSimplify()) { + change = removePostFailPlaces(change); + } + // Transform 24 - Pairwise Write Before Write + if (s.equals(absProperty.xform24) && absProperty.isSimplify()) { + change = weakWriteBeforeWrite(change); + } + // Transform 25 - Propagate Constant Variable Values + if (s.equals(absProperty.xform25) && absProperty.isSimplify()) { + change = propagateConst(change); + } + // Transform 19 - Merge Coordinated Variables + if (s.equals(absProperty.xform19) && absProperty.isSimplify()) { + change = mergeCoordinatedVars(change); + change = simplifyExpr(change); + } + // Transform 26 - Remove Dangling Transitions + if (s.equals(absProperty.xform26) && absProperty.isSimplify()) { + change = removeDanglingTransitions(change); + } + // Transform 28 - Combing Parallel Transitions (Abstraction) + if (s.equals(absProperty.xform28) && absProperty.isAbstract()) { + change = mergeTransitionsAbs(change); + } + // Transform 27 - Combine Parallel Transitions (Simplification) + else if (s.equals(absProperty.xform27) && absProperty.isSimplify()) { + change = mergeTransitionsSimp(change, true); + } + // Transform 29 - Remove Uninteresting Variables (Simplification) + if (s.equals(absProperty.xform29) && absProperty.isSimplify()) { + change = removeUninterestingVariables(change); + } + // Transform 21 - Normalize Delays + if (s.equals(absProperty.xform21) && absProperty.isAbstract() + && normalize) { + normalizeDelays(); + } + // Transform 31 - Simplify Delay Ranges + if (s.equals(absProperty.xform31) && absProperty.isAbstract()) { + change = maxSimpExpr(change); + } + } + change = true; + while (change && i < absProperty.maxIterations()) { + change = false; + divideProcesses(); + intVars = new ArrayList(); + for (String v : absProperty.getIntVars()) { + intVars.add(v); + } + for (Object o : absProperty.loopAbsModel.toArray()) { + String s = o.toString(); + if (s.equals(absProperty.xform12)) { + abstractAssign(); + } + // Transform 0 - Merge Parallel Places + if (s.equals(absProperty.xform0) && absProperty.isSimplify()) { + change = checkTrans0(change); + } + // Transform 1 - Remove a Place in a Self Loop + if (s.equals(absProperty.xform1) && absProperty.isSimplify()) { + change = checkTrans1(change); + } + // Transforms 5a, 6, 7 - Combine Transitions with the Same + // Preset + // and/or Postset + if ((s.equals(absProperty.xform5) || s.equals(absProperty.xform6) || s + .equals(absProperty.xform7)) + && absProperty.isAbstract()) { + change = checkTrans5(change); + } + // Transform 5b + if (s.equals(absProperty.xform5) && absProperty.isAbstract()) { + change = checkTrans5b(change); + } + // Transform 4 - Remove a Transition with a Single Place in the + // Preset + if (s.equals(absProperty.xform4) && absProperty.isSimplify()) { + change = checkTrans4(change); + } + // Transform 3 - Remove a Transition with a Single Place in the + // Postset + if (s.equals(absProperty.xform3) && absProperty.isSimplify()) { + change = checkTrans3(change); + } + // Transform 22 - Remove Vacuous Transitions (simplification) + if (s.equals(absProperty.xform22) && absProperty.isSimplify()) { + change = checkTrans22(change); + } + // Transform 23 - Remove Vacuous Transitions (abstraction) + if (s.equals(absProperty.xform22) && absProperty.isAbstract()) { + change = checkTrans23(change); + } + // Transform 14 - Remove Dead Places + if (s.equals(absProperty.xform14) && absProperty.isSimplify()) { + change = removeDeadPlaces(change); + } + // Transform 8 - Propagate local assignments + if (s.equals(absProperty.xform8) && absProperty.isSimplify()) { + change = checkTrans8(change); + } + // Transform 9 - Remove Write Before Write + if (s.equals(absProperty.xform9) && absProperty.isSimplify()) { + change = checkTrans9(change); + } + // Transform 10 - Simplify Expressions + if (s.equals(absProperty.xform10) && absProperty.isSimplify()) { + change = simplifyExpr(change); + } + // Transform 15 - Remove Dead Transitions + if (s.equals(absProperty.xform15) && absProperty.isSimplify()) { + change = removeDeadTransitions(change); + } + // Transform 17 - Remove Dominated Transitions + if (s.equals(absProperty.xform17) && absProperty.isSimplify()) { + change = removeDominatedTransitions(change); + change = removeRedundantTransitions(change); + } + // Transform 18 - Remove Unread Variables + if (s.equals(absProperty.xform18) && absProperty.isSimplify()) { + change = removeUnreadVars(change); + } + // Transform 20 - Remove Arc after Fail Transition + if (s.equals(absProperty.xform20) && absProperty.isSimplify()) { + change = removePostFailPlaces(change); + } + // Transform 24 - Pairwise Write Before Write + if (s.equals(absProperty.xform24) && absProperty.isSimplify()) { + change = weakWriteBeforeWrite(change); + } + // Transform 25 - Propagate Constant Variable Values + if (s.equals(absProperty.xform25) && absProperty.isSimplify()) { + change = propagateConst(change); + } + // Transform 19 - Merge Coordinated Variables + if (s.equals(absProperty.xform19) && absProperty.isSimplify()) { + change = mergeCoordinatedVars(change); + change = simplifyExpr(change); + } + // Transform 26 - Remove Dangling Transitions + if (s.equals(absProperty.xform26) && absProperty.isSimplify()) { + change = removeDanglingTransitions(change); + } + // Transform 28 - Combing Parallel Transitions (Abstraction) + if (s.equals(absProperty.xform28) && absProperty.isAbstract()) { + change = mergeTransitionsAbs(change); + } + // Transform 27 - Combine Parallel Transitions (Simplification) + else if (s.equals(absProperty.xform27) && absProperty.isSimplify()) { + change = mergeTransitionsSimp(change, true); + } + // Transform 29 - Remove Uninteresting Variables + // (Simplification) + if (s.equals(absProperty.xform29) && absProperty.isSimplify()) { + change = removeUninterestingVariables(change); + } + // Transform 30 - Remove Uninteresting Transitions + // (Simplification) + if (s.equals(absProperty.xform30) && absProperty.isSimplify()) { + change = removeUninterestingTransitions(change); + } + // Transform 21 - Normalize Delays + if (s.equals(absProperty.xform21) && absProperty.isAbstract() + && normalize) { + normalizeDelays(); + } + // Transform 31 - Simplify Delay Ranges + if (s.equals(absProperty.xform31) && absProperty.isAbstract()) { + change = maxSimpExpr(change); + } + } + i++; + } + for (Object o : absProperty.postAbsModel.toArray()) { + String s = o.toString(); + if (s.equals(absProperty.xform12)) { + abstractAssign(); + } + divideProcesses(); + intVars = new ArrayList(); + for (String v : absProperty.getIntVars()) { + intVars.add(v); + } + // Transform 0 - Merge Parallel Places + if (s.equals(absProperty.xform0) && absProperty.isSimplify()) { + change = checkTrans0(change); + } + // Transform 1 - Remove a Place in a Self Loop + if (s.equals(absProperty.xform1) && absProperty.isSimplify()) { + change = checkTrans1(change); + } + // Transforms 5a, 6, 7 - Combine Transitions with the Same + // Preset + // and/or Postset + if ((s.equals(absProperty.xform5) || s.equals(absProperty.xform6) || s + .equals(absProperty.xform7)) + && absProperty.isAbstract()) { + change = checkTrans5(change); + } + // Transform 5b + if (s.equals(absProperty.xform5) && absProperty.isAbstract()) { + change = checkTrans5b(change); + } + // Transform 4 - Remove a Transition with a Single Place in the + // Preset + if (s.equals(absProperty.xform4) && absProperty.isSimplify()) { + change = checkTrans4(change); + } + // Transform 3 - Remove a Transition with a Single Place in the + // Postset + if (s.equals(absProperty.xform3) && absProperty.isSimplify()) { + change = checkTrans3(change); + } + // Transform 22 - Remove Vacuous Transitions (simplification) + if (s.equals(absProperty.xform22) && absProperty.isSimplify()) { + change = checkTrans22(change); + } + // Transform 23 - Remove Vacuous Transitions (abstraction) + if (s.equals(absProperty.xform22) && absProperty.isAbstract()) { + change = checkTrans23(change); + } + // Transform 14 - Remove Dead Places + if (s.equals(absProperty.xform14) && absProperty.isSimplify()) { + change = removeDeadPlaces(change); + } + // Transform 8 - Propagate local assignments + if (s.equals(absProperty.xform8) && absProperty.isSimplify()) { + change = checkTrans8(change); + } + // Transform 9 - Remove Write Before Write + if (s.equals(absProperty.xform9) && absProperty.isSimplify()) { + change = checkTrans9(change); + } + // Transform 10 - Simplify Expressions + if (s.equals(absProperty.xform10) && absProperty.isSimplify()) { + change = simplifyExpr(change); + } + // Transform 15 - Remove Dead Transitions + if (s.equals(absProperty.xform15) && absProperty.isSimplify()) { + change = removeDeadTransitions(change); + } + // Transform 17 - Remove Dominated Transitions + if (s.equals(absProperty.xform17) && absProperty.isSimplify()) { + change = removeDominatedTransitions(change); + } + // Transform 18 - Remove Unread Variables + if (s.equals(absProperty.xform18) && absProperty.isSimplify()) { + change = removeUnreadVars(change); + } + // Transform 20 - Remove Arc after Fail Transition + if (s.equals(absProperty.xform20) && absProperty.isSimplify()) { + change = removePostFailPlaces(change); + } + // Transform 24 - Pairwise Write Before Write + if (s.equals(absProperty.xform24) && absProperty.isSimplify()) { + change = weakWriteBeforeWrite(change); + } + // Transform 25 - Propagate Constant Variable Values + if (s.equals(absProperty.xform25) && absProperty.isSimplify()) { + change = propagateConst(change); + } + // Transform 19 - Merge Coordinated Variables + if (s.equals(absProperty.xform19) && absProperty.isSimplify()) { + change = mergeCoordinatedVars(change); + change = simplifyExpr(change); + } + // Transform 26 - Remove Dangling Transitions + if (s.equals(absProperty.xform26) && absProperty.isSimplify()) { + change = removeDanglingTransitions(change); + } + // Transform 28 - Combing Parallel Transitions (Abstraction) + if (s.equals(absProperty.xform28) && absProperty.isAbstract()) { + change = mergeTransitionsAbs(change); + } + // Transform 27 - Combine Parallel Transitions (Simplification) + else if (s.equals(absProperty.xform27) && absProperty.isSimplify()) { + change = mergeTransitionsSimp(change, true); + } + // Transform 29 - Remove Uninteresting Variables + // (Simplification) + if (s.equals(absProperty.xform29) && absProperty.isSimplify()) { + change = removeUninterestingVariables(change); + } + // Transform 21 - Normalize Delays + if (s.equals(absProperty.xform21) && absProperty.isAbstract() + && normalize) { + normalizeDelays(); + } + // Transform 31 - Simplify Delay Ranges + if (s.equals(absProperty.xform31) && absProperty.isAbstract()) { + change = maxSimpExpr(change); + } + } + numTrans = transitions.size(); + numPlaces = places.size(); + numVars = variables.size(); + if (print) { + System.out.println("Transitions after abstraction: " + numTrans); + System.out.println("Places after abstraction: " + numPlaces); + System.out.println("Variables after abstraction: " + numVars); + Double stop = (System.nanoTime() - start) * 1.0e-9; + System.out.println("Total Abstraction Time: " + stop.toString() + + " s"); + System.out.println("Number of Main Abstraction Loop Iterations: " + + i.toString()); + } + } + + public void abstractVars(String[] intVars) { + // Remove uninteresting variables + ArrayList interestingVars = getIntVars(intVars); + ArrayList vars = new ArrayList(); // The list of + // uninteresting variables + for (Variable s : variables) { + if (!interestingVars.contains(s.getName())) { + vars.add(s.getName()); + } + } + for (String s : vars) { + for (Transition t : transitions.values()) { + if (t.getAssignments().containsKey(s)) { + // Remove assignments to removed variables + t.removeAssignment(s); + } + } + // Set initial condition of removed variables to "unknown" + if (booleans.containsKey(s)) { + booleans.get(s).addInitValue("unknown"); + } else if (continuous.containsKey(s)) { + Properties prop = new Properties(); + prop.setProperty("value", "[-INF,INF]"); + prop.setProperty("rate", "[-INF,INF]"); + continuous.get(s).addInitCond(prop); + } else if (integers.containsKey(s)) { + integers.get(s).addInitValue("[-INF,INF]"); + } + } + } + + public void abstractAssign() { + for (Transition t : transitions.values()) { + if (t.getPostset().length > 0) { + Place[] postset = t.getPostset(); + for (Place p : postset) { + if (p.getPostset().length > 0) { + Transition[] postTrans = p.getPostset(); + for (Transition tP : postTrans) { + boolean flag = true; + HashMap contAssignments = tP + .getContAssignments(); + if (contAssignments.containsKey(tP.getLabel())) { + for (String var : contAssignments.keySet()) { + if (!t.getContAssignments() + .containsKey(var) + || (tP.getContAssignTree(var).isit != 'c')) { + flag = false; + } + } + } else { + flag = false; + } + HashMap intAssignments = tP + .getIntAssignments(); + if (intAssignments.containsKey(tP.getLabel())) { + for (String var : intAssignments.keySet()) { + if (!t.getIntAssignments().containsKey(var) + || (tP.getIntAssignTree(var).isit != 'c')) { + flag = false; + } + } + } else { + flag = false; + } + HashMap boolAssignments = tP + .getBoolAssignments(); + if (boolAssignments.containsKey(tP.getLabel())) { + for (String var : boolAssignments.keySet()) { + if (!t.getBoolAssignments() + .containsKey(var) + || (tP.getBoolAssignTree(var).isit != 'c')) { + flag = false; + } + } + } else { + flag = false; + } + if (flag) { + for (String var : contAssignments.keySet()) { + String[] assign = { + contAssignments.get(var).toString(), + contAssignments.get(var).toString() }; + String[][] assignRange = new String[2][2]; + Pattern pattern = Pattern + .compile("\\[(\\S+?),(\\S+?)\\]"); + for (int i = 0; i < assign.length; i++) { + Matcher matcher = pattern + .matcher(assign[i]); + if (matcher.find()) { + assignRange[i][0] = matcher + .group(1); + assignRange[i][1] = matcher + .group(2); + } else { + assignRange[i][0] = assign[i]; + assignRange[i][1] = assign[i]; + } + } + if (assignRange[0][0].equals("inf")) { + assign[0] = assignRange[1][0]; + } else if (assignRange[1][0].equals("inf")) { + assign[0] = assignRange[0][0]; + } else if (Float + .parseFloat(assignRange[0][0]) < Float + .parseFloat(assignRange[1][0])) { + assign[0] = assignRange[0][0]; + } else { + assign[0] = assignRange[1][0]; + } + if (assignRange[0][1].equals("inf") + || assignRange[1][1].equals("inf")) { + assign[1] = "inf"; + } else if (Float + .parseFloat(assignRange[0][1]) > Float + .parseFloat(assignRange[1][1])) { + assign[1] = assignRange[0][1]; + } else { + assign[1] = assignRange[1][1]; + } + if (assign[0].equals(assign[1])) { + tP.addContAssign(var, assign[0]); + } else { + tP.addContAssign(var, "[" + assign[0] + + "," + assign[1] + "]"); + } + } + for (String var : intAssignments.keySet()) { + String[] assign = { + intAssignments.get(var).toString(), + intAssignments.get(var).toString() }; + String[][] assignRange = new String[2][2]; + Pattern pattern = Pattern + .compile("\\[(\\S+?),(\\S+?)\\]"); + for (int i = 0; i < assign.length; i++) { + Matcher matcher = pattern + .matcher(assign[i]); + if (matcher.find()) { + assignRange[i][0] = matcher + .group(1); + assignRange[i][1] = matcher + .group(2); + } else { + assignRange[i][0] = assign[i]; + assignRange[i][1] = assign[i]; + } + } + if (assignRange[0][0].equals("inf")) { + assign[0] = assignRange[1][0]; + } else if (assignRange[1][0].equals("inf")) { + assign[0] = assignRange[0][0]; + } else if (Integer + .parseInt(assignRange[0][0]) < Integer + .parseInt(assignRange[1][0])) { + assign[0] = assignRange[0][0]; + } else { + assign[0] = assignRange[1][0]; + } + if (assignRange[0][1].equals("inf") + || assignRange[1][1].equals("inf")) { + assign[1] = "inf"; + } else if (Integer + .parseInt(assignRange[0][1]) > Integer + .parseInt(assignRange[1][1])) { + assign[1] = assignRange[0][1]; + } else { + assign[1] = assignRange[1][1]; + } + if (assign[0].equals(assign[1])) { + tP.addIntAssign(var, assign[0]); + } else { + tP.addIntAssign(var, "[" + assign[0] + + "," + assign[1] + "]"); + } + } + for (String var : boolAssignments.keySet()) { + String[] assign = { + boolAssignments.get(var).toString(), + boolAssignments.get(var).toString() }; + String[][] assignRange = new String[2][2]; + Pattern pattern = Pattern + .compile("\\[(\\S+?),(\\S+?)\\]"); + for (int i = 0; i < assign.length; i++) { + Matcher matcher = pattern + .matcher(assign[i]); + if (matcher.find()) { + assignRange[i][0] = matcher + .group(1); + assignRange[i][1] = matcher + .group(2); + } else { + assignRange[i][0] = assign[i]; + assignRange[i][1] = assign[i]; + } + } + if (assignRange[0][0].equals("false") + || assignRange[1][0] + .equals("false")) { + assign[0] = "false"; + } else { + assign[0] = "true"; + } + if (assignRange[0][1].equals("true") + || assignRange[1][1].equals("true")) { + assign[1] = "true"; + } else { + assign[1] = "false"; + } + if (assign[0].equals(assign[1])) { + tP.addBoolAssign(var, assign[0]); + } else { + tP.addBoolAssign(var, "[" + assign[0] + + "," + assign[1] + "]"); + } + } + } + } + } + } + } + } + } + + private boolean removeDeadPlaces(boolean change) { + ArrayList removePlace = new ArrayList(); + for (Place p : places.values()) { + if (p.getPreset().length == 0 && !p.isMarked()) {// If the place is + // initially unmarked and has no preset + for (Transition t : p.getPostset()) { // Remove each transition + // in the post set + removeMovement(p.getName(), t.getLabel()); + for (Place pP : t.getPostset()) { + removeMovement(t.getLabel(), pP.getName()); + } + removeTransition(t.getLabel()); + } + removePlace.add(p.getName()); + change = true; + continue; + } + if (p.getPreset().length == 0 && p.getPostset().length == 0) { + removePlace.add(p.getName()); // Remove unconnected places + } + } + for (Place p : places.values()) { + if (!change + && (absProperty.preAbsModel.contains(absProperty.xform15) + || absProperty.loopAbsModel.contains(absProperty.xform15) || absProperty.postAbsModel + .contains(absProperty.xform15))) { + if (p.isMarked()) + continue; + ArrayList list = new ArrayList(); + if (hasMarkedPreset(p, list)) // If the place is not + // recursively dead + continue; + for (Transition t : p.getPostset()) { + removeMovement(p.getName(), t.getLabel()); // Remove all + // transitions in its post set + for (Place pP : t.getPostset()) { + removeMovement(t.getLabel(), pP.getName()); + } + removeTransition(t.getLabel()); + } + for (Transition t : p.getPreset()) { + removeMovement(t.getLabel(), p.getName()); // Remove all + // transitions in its preset + } + removePlace.add(p.getName()); + change = true; + } + } + for (String s : removePlace) { + removePlace(s); + } + return change; + } + + private boolean removeDeadTransitions(boolean change) { + HashMap initVars = new HashMap(); + for (Variable v : variables) { + initVars.put(v.getName(), v.getInitValue()); + } + ArrayList removeTrans = new ArrayList(); + ArrayList removeEnab = new ArrayList(); + for (Transition t : transitions.values()) { + ExprTree expr = t.getEnablingTree(); + if (expr == null) { + continue; + } + if (expr.isit == 't') { + if (expr.uvalue == 0 + && (absProperty.preAbsModel.contains(absProperty.xform16) + || absProperty.loopAbsModel.contains(absProperty.xform16) || absProperty.postAbsModel + .contains(absProperty.xform16)) + && absProperty.isSimplify()) { + // If the enabling condition is constant false + removeTrans.add(t.getLabel()); + } else if (expr.lvalue == 1 + && (absProperty.preAbsModel.contains(absProperty.xform15) + || absProperty.loopAbsModel.contains(absProperty.xform15) || absProperty.postAbsModel + .contains(absProperty.xform15)) + && absProperty.isSimplify()) { + // If the enabling condition is constant true + removeEnab.add(t.getLabel()); + } + } + // If the enabling condition is initially true + if ((absProperty.preAbsModel.contains(absProperty.xform16) + || absProperty.loopAbsModel.contains(absProperty.xform16) || absProperty.postAbsModel + .contains(absProperty.xform16)) + && (expr.evaluateExpr(initVars) == 1) + && absProperty.isSimplify()) { + boolean enabled = true; + for (Transition tP : transitions.values()) { + if (!tP.equals(t) + && expr.getChange(tP.getAssignments()) == 'F' + || expr.getChange(tP.getAssignments()) == 'f' + || expr.getChange(tP.getAssignments()) == 'X') { + enabled = false; + break; + } + } + if (enabled) { + removeEnab.add(t.getLabel()); + } + } + // If the enabling condition is initially false + else if ((absProperty.preAbsModel.contains(absProperty.xform11) + || absProperty.loopAbsModel.contains(absProperty.xform11) || absProperty.postAbsModel + .contains(absProperty.xform11)) + && (expr.evaluateExpr(initVars) == 0) + && absProperty.isSimplify()) { + boolean disabled = true; + for (Transition tP : transitions.values()) { + if (!tP.getLabel().equals(t) + && expr.getChange(tP.getAssignments()) == 'T' + || expr.getChange(tP.getAssignments()) == 't' + || expr.getChange(tP.getAssignments()) == 'X') { + disabled = false; + break; + } + } + if (disabled) { + removeTrans.add(t.getLabel()); + } + } + } + for (String t : removeEnab) { + transitions.get(t).removeEnabling(); + } + if (absProperty.preAbsModel.contains(absProperty.xform15) + || absProperty.loopAbsModel.contains(absProperty.xform15) + || absProperty.postAbsModel.contains(absProperty.xform15)) { + for (String t : removeTrans) { + Transition trans = transitions.get(t); + for (Place p : trans.getPreset()) { + removeMovement(p.getName(), t); + } + for (Place p : trans.getPostset()) { + removeMovement(t, p.getName()); + } + removeTransition(t); + } + } + return change; + } + + private boolean removeDominatedTransitions(boolean change) { + for (Place p : places.values()) { + for (Transition t : p.getPostset()) { + for (Transition tP : p.getPostset()) { + boolean flag = false; + if (!t.equals(tP)) { + if (t.getEnablingTree() == null) { + continue; + } else if (tP.getEnablingTree() == null) { + flag = true; + } else if (tP.getEnablingTree().implies( + t.getEnablingTree())) { + flag = true; + } + if (!t.getDelay().contains("uniform") + && !t.getDelay().matches("[\\d-]+")) { + continue; + } + } + if (flag) { + String delayT = t.getDelay(); + String delayTP = t.getDelay(); + if (delayT != null && delayTP != null) { + Pattern rangePattern = Pattern + .compile("uniform\\(([\\d]+),([\\d]+)\\)"); + Matcher delayTMatcher = rangePattern + .matcher(delayT); + Matcher delayTpMatcher = rangePattern + .matcher(delayTP); + if (delayTMatcher.find() && delayTpMatcher.find()) { + String lower = delayTpMatcher.group(1); + String upper = delayTMatcher.group(2); + if (Integer.parseInt(lower) > Integer + .parseInt(upper)) { + for (Place s : tP.getPreset()) { + removeMovement(s.getName(), tP + .getLabel()); + } + for (Place s : tP.getPreset()) { + removeMovement(tP.getLabel(), s + .getName()); + } + removeTransition(tP.getLabel()); + change = true; + } + } + } + } + } + } + } + return change; + } + + private boolean removeRedundantTransitions(boolean change) { + for (Place p : places.values()) { + for (Transition t : p.getPostset()) { + for (Transition tP : p.getPostset()) { + if (t.getEnabling() != null || tP.getEnabling() != null) { + if (t.getEnabling() != null && tP.getEnabling() != null) { + if (!t.getEnabling().equals(tP.getEnabling())) { + continue; + } + } else { + continue; + } + } + if (!t.getBoolAssignments().equals(tP.getBoolAssignments())) { + continue; + } + if (!t.getIntAssignments().equals(tP.getIntAssignments())) { + continue; + } + if (!t.getContAssignments().equals(tP.getContAssignments())) { + continue; + } + if (!t.getRateAssignments().equals(t.getRateAssignments())) { + continue; + } + if (!t.equals(tP) && t.getDelay() != null + && tP.getDelay() != null) { + String delayT = t.getDelay(); + String delayTP = tP.getDelay(); + if (!delayT.contains("uniform") + && !delayT.matches("[\\d-]+") + || !delayTP.contains("uniform") + && !delayTP.matches("[\\d-]+")) { + continue; + } + Pattern rangePattern = Pattern + .compile("uniform\\(([\\d]+),([\\d]+)\\)"); + Matcher delayTMatcher = rangePattern.matcher(delayT); + Matcher delayTpMatcher = rangePattern.matcher(delayTP); + if (delayTMatcher.find() && delayTpMatcher.find()) { + Integer lower, upper; + Integer lower1 = Integer.parseInt(delayTpMatcher + .group(1)); + Integer upper1 = Integer.parseInt(delayTpMatcher + .group(2)); + Integer lower2 = Integer.parseInt(delayTMatcher + .group(1)); + Integer upper2 = Integer.parseInt(delayTMatcher + .group(2)); + if (lower1 < lower2) { + lower = lower1; + } else { + lower = lower2; + } + if (upper1 > upper2) { + upper = upper1; + } else { + upper = upper2; + } + for (Place s : tP.getPreset()) { + removeMovement(s.getName(), tP.getLabel()); + } + for (Place s : tP.getPostset()) { + removeMovement(tP.getLabel(), s.getName()); + } + String delay = "uniform(" + lower.toString() + "," + + upper.toString() + ")"; + t.addDelay(delay); + removeTransition(tP.getLabel()); + change = true; + } + } + } + } + } + return change; + } + + private boolean removePostFailPlaces(boolean change) { + for (Transition t : transitions.values()) { + if (t.isFail()) { + for (Place p : t.getPostset()) { + removeMovement(t.getLabel(), p.getName()); + } + } + } + return change; + } + + private boolean removeUnreadVars(boolean change) { + ArrayList remove = new ArrayList(); + for (Variable v : variables) { + if (intVars.contains(v.getName())) { + continue; + } + String s = v.getName(); + boolean isRead = false; + for (Transition t : transitions.values()) { + ExprTree enab = t.getEnablingTree(); + if (enab != null) { + if (enab.containsVar(s)) { + isRead = true; + break; + } + } + ExprTree delay = t.getDelayTree(); + if (delay != null) { + if (delay.containsVar(s)) { + isRead = true; + break; + } + } + HashMap boolAssignTrees = t + .getBoolAssignTrees(); + for (ExprTree e : boolAssignTrees.values()) { + if (e != null) { + if (e.containsVar(s)) { + isRead = true; + break; + } + } + } + HashMap intAssignTrees = t + .getIntAssignTrees(); + for (ExprTree e : intAssignTrees.values()) { + if (e != null) { + if (e.containsVar(s)) { + isRead = true; + break; + } + } + } + HashMap contAssignTrees = t + .getContAssignTrees(); + for (ExprTree e : contAssignTrees.values()) { + if (e != null) { + if (e.containsVar(s)) { + isRead = true; + break; + } + } + } + HashMap rateAssignTrees = t + .getRateAssignTrees(); + for (ExprTree e : rateAssignTrees.values()) { + if (e != null) { + if (e.containsVar(s)) { + isRead = true; + break; + } + } + } + } + if (!isRead) { + remove.add(s); + change = true; + } + } + for (String s : remove) { + removeAllAssignVar(s); + removeVar(s); + } + return change; + } + + private boolean mergeCoordinatedVars(boolean change) { + ArrayList remove = new ArrayList(); + ArrayList merge = new ArrayList(); + HashMap mergeInverse = new HashMap(); + for (Variable var1 : booleans.values()) { + for (Variable var2 : booleans.values()) { + if (var1.equals(var2)) + continue; + if (intVars.contains(var2)) + continue; + boolean same = areCorrelatedBooleans(var1.getName(), var2 + .getName()); + boolean invert = areInverted(var1.getName(), var2.getName()); + if (same) { + if (variables.contains(var1) + && variables.contains(var2) + && (process_read.get(var2.getName()) != -1 || process_read + .get(var1.getName()) == -1)) { + String[] temp = { var1.getName(), var2.getName() }; + merge.add(temp); + remove.add(var2.getName()); + change = true; + } + } else if (invert) { + ExprTree expr = new ExprTree(this); + expr.token = expr.intexpr_gettok("~" + var1.getName()); + expr.intexpr_L("~" + var1.getName()); + if (process_read.get(var2.getName()) != -1 + || process_read.get(var1.getName()) == -1) { + mergeInverse.put(var2.getName(), expr); + remove.add(var2.toString()); + } + } + } + } + for (Variable var1 : continuous.values()) { + for (Variable var2 : continuous.values()) { + if (var1.equals(var2)) + continue; + boolean same = areCorrelatedContinuous(var1.getName(), var2 + .getName()); + if (same) { + if (variables.contains(var1) + && variables.contains(var2) + && (process_read.get(var2.getName()) != -1 || process_read + .get(var1.getName()) == -1)) { + String[] temp = { var1.getName(), var2.getName() }; + merge.add(temp); + remove.add(var2.getName()); + change = true; + } + } + } + } + for (Variable var1 : integers.values()) { + for (Variable var2 : integers.values()) { + if (var1.equals(var2)) + continue; + boolean same = areCorrelatedIntegers(var1.getName(), var2 + .getName()); + if (same) { + if (variables.contains(var1) + && variables.contains(var2) + && (process_read.get(var2.getName()) != -1 || process_read + .get(var1.getName()) == -1)) { + String[] temp = { var1.getName(), var2.getName() }; + merge.add(temp); + remove.add(var2.getName()); + change = true; + } + } + } + } + for (String[] s : merge) { + mergeVariables(s[0], s[1]); + } + for (String s : mergeInverse.keySet()) { + mergeVariables(mergeInverse.get(s), s); + } + for (String s : remove) { + removeVar(s); + } + return change; + } + + private boolean hasMarkedPreset(Place place, ArrayList list) { + if (list.contains(place)) { + return false; + } + list.add(place); + for (Transition t : place.getPreset()) { + for (Place p : t.getPreset()) { + if (p.isMarked()) + return true; + else if (hasMarkedPreset(p, list)) + return true; + } + } + return false; + } + + private ArrayList getIntVars(String[] oldIntVars) { + ArrayList intVars = new ArrayList(); + if (booleans.containsKey("fail")) + intVars.add("fail"); + else if (booleans.containsKey("shutdown")) + intVars.add("shutdown"); + for (String s : oldIntVars) { + if (!intVars.contains(s)) + intVars.add(s); + } + ArrayList tempIntVars = new ArrayList(); + tempIntVars = intVars; + do { + intVars = new ArrayList(); + for (String s : tempIntVars) { + intVars.add(s); + } + for (Transition t : transitions.values()) { + for (ExprTree e : t.getContAssignTrees().values()) { + tempIntVars.addAll(e.getVars()); + } + for (ExprTree e : t.getRateAssignTrees().values()) { + tempIntVars.addAll(e.getVars()); + } + for (ExprTree e : t.getIntAssignTrees().values()) { + tempIntVars.addAll(e.getVars()); + } + for (ExprTree e : t.getBoolAssignTrees().values()) { + tempIntVars.addAll(e.getVars()); + } + } + } while (!intVars.equals(tempIntVars)); + tempIntVars = intVars; + do { + intVars = new ArrayList(); + for (String s : tempIntVars) { + intVars.add(s); + } + for (String var : intVars) { + ArrayList process = new ArrayList(); + for (Transition t : transitions.values()) { + if (t.getAssignments().containsKey(var)) { + process.add(t); + } + } + ArrayList tempProcess = new ArrayList(); + for (Transition t : process) { + tempProcess.add(t); + } + do { + process = new ArrayList(); + process.addAll(tempProcess); + for (Transition t : process) { + for (Place p : t.getPostset()) { + for (Transition tP : p.getPostset()) { + if (!tempProcess.contains(tP)) { + tempProcess.add(tP); + } + } + } + for (Place p : t.getPreset()) { + for (Transition tP : p.getPreset()) { + if (!tempProcess.contains(tP)) { + tempProcess.add(tP); + } + } + } + } + } while (!tempProcess.equals(process)); + for (Transition trans : process) { + for (String s : trans.getEnablingTree().getVars()) { + if (!tempIntVars.contains(s)) + tempIntVars.add(s); + } + } + } + } while (!intVars.equals(tempIntVars)); + return intVars; + } + + private static boolean comparePreset(Place p1, Place p2) { + Transition[] pre1 = p1.getPreset(); + Transition[] pre2 = p2.getPreset(); + if (pre1.length != pre2.length || pre1.length == 0) { + return false; + } + for (Transition t1 : pre1) { + boolean contains = false; + for (Transition t2 : pre2) { + if (t1 == t2) { + contains = true; + break; + } + } + if (!contains) { + return false; + } + } + return true; + } + + private static boolean comparePreset(Place p1, Place p2, Transition trans1, + Transition trans2) { + Transition[] set1 = p1.getPreset(); + Transition[] set2 = p2.getPreset(); + if (set1.length != set2.length || set1.length == 0) { + return false; + } + for (Transition t1 : set1) { + boolean contains = false; + for (Transition t2 : set2) { + if (t1.equals(t2) || t1.equals(trans1) || t1.equals(trans2)) { + contains = true; + } + } + if (!contains) { + return false; + } + } + return true; + } + + private static boolean comparePreset(Transition t1, Transition t2) { + Place[] pre1 = t1.getPreset(); + Place[] pre2 = t2.getPreset(); + if (pre1.length != pre2.length || pre1.length == 0) { + return false; + } + for (Place p1 : pre1) { + boolean contains = false; + for (Place p2 : pre2) { + if (p1.equals(p2)) { + contains = true; + break; + } + } + if (!contains) { + return false; + } + } + return true; + } + + private static boolean comparePostset(Place p1, Place p2) { + Transition[] pre1 = p1.getPostset(); + Transition[] pre2 = p2.getPostset(); + if (pre1.length != pre2.length || pre1.length == 0) { + return false; + } + for (Transition t1 : pre1) { + boolean contains = false; + for (Transition t2 : pre2) { + if (t1.equals(t2)) { + contains = true; + break; + } + } + if (!contains) { + return false; + } + } + return true; + } + + private static boolean comparePostset(Place p1, Place p2, Transition trans1, + Transition trans2) { + Transition[] set1 = p1.getPostset(); + Transition[] set2 = p2.getPostset(); + if (set1.length != set2.length || set1.length == 0) { + return false; + } + for (Transition t1 : set1) { + boolean contains = false; + for (Transition t2 : set2) { + if (t1.equals(t2) || t1.equals(trans1) || t1.equals(trans2)) { + contains = true; + } + } + if (!contains) { + return false; + } + } + return true; + } + + private static boolean comparePostset(Transition t1, Transition t2) { + Place[] post1 = t1.getPostset(); + Place[] post2 = t2.getPostset(); + if (post1.length != post1.length || post1.length == 0) { + return false; + } + for (Place p1 : post1) { + boolean contains = false; + for (Place p2 : post2) { + if (p1.equals(p2)) { + contains = true; + break; + } + } + if (!contains) { + return false; + } + } + return true; + } + + private void combinePlaces(Place place1, Place place2) { + for (Transition t : place1.getPreset()) { + addMovement(t.getLabel(), place1.getName()); + removeMovement(t.getLabel(), place2.getName()); + } + for (Transition t : place1.getPostset()) { + addMovement(place1.getName(), t.getLabel()); + removeMovement(place2.getName(), t.getLabel()); + } + removePlace(place2.getName()); + } + + private boolean checkTrans0(boolean change) { + ArrayList merge = new ArrayList(); + for (Place p1 : places.values()) { + for (Place p2 : places.values()) { + if (!p1.equals(p2)) { + boolean assign = false; + if (comparePreset(p1, p2) && comparePostset(p1, p2) + && (p1.isMarked() == p2.isMarked()) && !assign) { + Place[] temp = { p1, p2 }; + merge.add(temp); + } + } + } + } + for (Place[] a : merge) { + change = true; + combinePlaces(a[0], a[1]); + } + return change; + } + + private boolean checkTrans1(boolean change) { + ArrayList remove = new ArrayList(); + for (Place p : places.values()) { + Transition[] preset = p.getPreset(); + Transition[] postset = p.getPostset(); + if (preset.length == 1 && postset.length == 1) { + if (preset[0].equals(postset[0]) && !p.isMarked()) { + remove.add(p); + } else { + continue; + } + } + } + for (Place p : remove) { + change = true; + removePlace(p.getName()); + } + return change; + } + + private boolean checkTrans5(boolean change) { + ArrayList combine = new ArrayList(); + HashMap samesets = new HashMap(); + for (Transition t1 : transitions.values()) { + if (!(t1.getDelayTree().isit == 'n' || (t1.getDelayTree().isit == 'a' && t1 + .getDelayTree().op.equals("uniform")))) { + continue; + } + for (Transition t2 : transitions.values()) { + if (!(t2.getDelayTree().isit == 'n' || (t2.getDelayTree().isit == 'a' && t2 + .getDelayTree().op.equals("uniform")))) { + continue; + } + if (!t1.equals(t2)) { + boolean samePreset = comparePreset(t1, t2); + boolean samePostset = comparePostset(t1, t2); + boolean assign = hasAssignments(t1) || hasAssignments(t2); + if ((samePreset && samePostset) && !assign) { + Transition[] array = { t1, t2 }; + boolean[] same = { samePreset, samePostset }; + combine.add(array); + samesets.put(t1, same); + } else if (samePreset && !assign + && absProperty.preAbsModel.contains(absProperty.xform6) || absProperty.loopAbsModel.contains(absProperty.xform6) || absProperty.postAbsModel.contains(absProperty.xform6)) { + Place[] postset1 = t1.getPostset(); + Place[] postset2 = t2.getPostset(); + if (postset1.length == 1 && postset2.length == 1) { + if (comparePreset( + places.get(postset1[0].getName()), places + .get(postset2[0].getName()), t1, t2)) { + Transition[] array = { t1, t2 }; + boolean[] same = { samePreset, samePostset }; + combine.add(array); + samesets.put(t1, same); + } + } + } else if (samePostset + && !assign + && (absProperty.preAbsModel.contains(absProperty.xform7) + || absProperty.loopAbsModel + .contains(absProperty.xform27) || absProperty.postAbsModel + .contains(absProperty.xform27))) { + Place[] preset1 = t1.getPreset(); + Place[] preset2 = t1.getPreset(); + if (preset1.length == 1 && preset2.length == 1) { + if (comparePostset( + places.get(preset1[0].getName()), places + .get(preset2[0].getName()), t1, t2) + && !t2.isFail()) { + Transition[] array = { t1, t2 }; + boolean[] same = { samePreset, samePostset }; + combine.add(array); + samesets.put(t1, same); + } + } + } + } + } + } + for (Transition[] s : combine) { + change = true; + combineTransitions(s[0], s[1], samesets.get(s[0])[0], samesets + .get(s[0])[1]); + } + return change; + } + + private boolean checkTrans5b(boolean change) { + ArrayList combine = new ArrayList(); + for (Transition t1 : transitions.values()) { + if (!(t1.getDelayTree().isit == 'n' || (t1.getDelayTree().isit == 'a' && t1 + .getDelayTree().op.equals("uniform")))) { + continue; + } + for (Transition t2 : transitions.values()) { + if (!(t2.getDelayTree().isit == 'n' || (t2.getDelayTree().isit == 'a' && t2 + .getDelayTree().op.equals("uniform")))) { + continue; + } + boolean transform = true; + if (!t1.equals(t2)) { + boolean assign = hasAssignments(t1) || hasAssignments(t2); + if (!assign) { + for (Place p1 : t1.getPreset()) { + if (transform) { + for (Place p2 : t2.getPreset()) { + if (!p1.equals(p2)) { + if (!comparePreset(p1, p2)) { + transform = false; + break; + } + } + } + } + } + } + if (transform) { + for (Place p1 : t1.getPostset()) { + for (Place p2 : t2.getPostset()) { + if (!p1.equals(p2)) { + if (!comparePostset(p1, p2)) { + transform = false; + break; + } + } + } + } + } + if (transform && !assign) { + Transition[] array = { t1, t2 }; + combine.add(array); + } + } + } + } + for (Transition[] s : combine) { + if (!s[1].isFail()) { + change = true; + combineTransitions(s[0], s[1], true, true); + } + } + return change; + } + + private boolean checkTrans3(boolean change) { + // Remove a transition with a single place in the postset + ArrayList remove = new ArrayList(); + for (Transition t : transitions.values()) { + Place[] postset = t.getPostset(); + if (postset.length == 1 && !postset[0].equals("")) { + boolean assign = hasAssignments(t); + boolean post = true; + for (Place p : t.getPreset()) { + if (p.getPostset().length != 1) { + post = false; + } + } + if ((postset[0].getPreset().length == 1 || post) && !assign) { + remove.add(t); + } + } + } + for (Transition t : remove) { + Place[] postset = t.getPostset(); + if (postset.length == 1 && !t.isFail()) { + if (removeTrans3(t)) + change = true; + } + } + return change; + } + + private boolean checkTrans4(boolean change) { + // Remove a Transition with a Single Place in the Preset + ArrayList remove = new ArrayList(); + for (Transition t : transitions.values()) { + Place[] preset = t.getPreset(); + if (preset.length == 1) { + boolean assign = hasAssignments(t); + boolean pre = true; + for (Place p : t.getPostset()) { + if (p.getPreset().length != 1) { + pre = false; + } + } + Transition[] postset = preset[0].getPostset(); + if ((postset.length == 1 || pre) + && places.containsKey(preset[0])) { + if (!assign) { + remove.add(t); + } + } + } + } + for (Transition t : remove) { + if (!t.isFail()) { + if (removeTrans4(t)) + change = true; + } + } + return change; + } + + private boolean checkTrans22(boolean change) { + // Remove Vacuous Transitions - Abstraction + ArrayList remove = new ArrayList(); + for (Transition t : transitions.values()) { + if (!(t.getDelayTree().isit == 'n' || (t.getDelayTree().isit == 'a' && t + .getDelayTree().op.equals("uniform")))) { + continue; + } + Place[] postset = t.getPostset(); + Place[] preset = t.getPreset(); + if (postset.length == 1 && preset.length == 1) { + boolean assign = false; + if (isGloballyDisabled(t)) { + assign = true; + break; + } + if (!assign) { + if (t.getAssignments().size() > 0) { + assign = true; + } + } + boolean post = true; + Transition[] tempPreset; + for (Place p : t.getPreset()) { + if (p.getPostset().length != 1) { + post = false; + } + } + tempPreset = postset[0].getPreset(); + if (!((tempPreset.length == 1 || post) && !assign)) { + assign = true; + } + boolean pre = true; + for (Place p : t.getPostset()) { + if (p.getPreset().length != 1) { + pre = false; + } + } + Transition[] tempPostset = preset[0].getPostset(); + if ((tempPostset.length == 1 || pre) + && places.containsKey(preset[0])) { + if (!assign) { + remove.add(t); + } + } + } + } + for (Transition t : remove) { + Place[] postset = t.getPostset(); + if (postset.length == 1 && !postset[0].equals("") && !t.isFail()) { + if (removeVacTransAbs(t)) + change = true; + } + } + return change; + } + + private boolean checkTrans23(boolean change) { + // Remove Vacuous Transitions + ArrayList remove = new ArrayList(); + for (Transition t : transitions.values()) { + if (!(t.getDelayTree().isit == 'n' || (t.getDelayTree().isit == 'a' && t + .getDelayTree().op.equals("uniform")))) { + continue; + } + Place[] postset = t.getPostset(); + Place[] preset = t.getPreset(); + if (postset.length == 1 && preset.length == 1) { + boolean assign = false; + if (t.getEnablingTree() != null && !t.isPersistent()) { + for (String var : t.getEnablingTree().getVars()) { + if (!process_write.get(var) + .equals(process_trans.get(t))) { + assign = true; + break; + } + } + } + if (t.getDelayTree().isit == 'a') { + if (!t.getDelayTree().op.equals("uniform") + || t.getDelayTree().r1.isit != 'n' + || t.getDelayTree().r2.isit != 'n') { + assign = true; + break; + } + } else if (t.getDelayTree().isit != 'n') { + assign = true; + break; + } + if (!assign) { + if (t.getAssignments().size() > 0) { + assign = true; + } + } + boolean post = true; + Transition[] tempPreset; + for (Place p : t.getPreset()) { + if (p.getPostset().length != 1) { + post = false; + } + } + tempPreset = postset[0].getPreset(); + if (!((tempPreset.length == 1 || post) && !assign)) { + assign = true; + } + boolean pre = true; + for (Place p : t.getPostset()) { + if (p.getPreset().length != 1) { + pre = false; + } + } + Transition[] tempPostset = preset[0].getPostset(); + if ((tempPostset.length == 1 || pre) + && places.containsKey(preset[0].getName())) { + if (!assign) { + remove.add(t); + } + } + } + } + for (Transition t : remove) { + Place[] postset = t.getPostset(); + if (postset.length == 1 && !postset[0].equals("") && !t.isFail()) { + if (removeVacTrans(t)) + change = true; + } + } + return change; + } + + private boolean checkTrans8(boolean change) { + // Propagate expressions of local variables to transition post sets + ArrayList initMarking = new ArrayList(); + ArrayList unvisited = new ArrayList(); + unvisited.addAll(transitions.values()); + for (Place p : places.values()) { + if (p.isMarked()) { + initMarking.add(p); + } + } + for (int i = 0; i < 2; i++) { + for (Place p : initMarking) { + for (Transition t : p.getPostset()) { + change = trans8Iteration(t, unvisited, change); + } + } + } + return change; + } + + private boolean checkTrans9(boolean change) { + // Remove Write Before Write + ArrayList remove = new ArrayList(); + for (Transition t : transitions.values()) { + for (String var : t.getAssignments().keySet()) { + if (intVars.contains(var)) { + continue; + } + read = new ArrayList(); + if ((process_read.get(var).equals(process_trans.get(t)) && process_write + .get(var).equals(process_trans.get(t))) + && !readBeforeWrite(t, var)) { + String[] temp = { t.getLabel(), var }; + remove.add(temp); + } + } + } + for (String[] temp : remove) { + transitions.get(temp[0]).removeAssignment(temp[1]); + change = true; + } + return change; + } + + private boolean weakWriteBeforeWrite(boolean change) { + ArrayList remove = new ArrayList(); + for (Transition t : transitions.values()) { + for (String var : t.getAssignments().keySet()) { + if (intVars.contains(var)) { + continue; + } + read = new ArrayList(); + // Check read variables for global writes + if ((process_read.get(var).equals(process_trans.get(t)) && process_write + .get(var).equals(process_trans.get(t))) + && !weakReadBeforeWrite(t, var)) { + String[] temp = { t.getLabel(), var }; + remove.add(temp); + } + } + } + for (String[] temp : remove) { + transitions.get(temp[0]).removeAssignment(temp[1]); + change = true; + } + return change; + } + + private boolean removeUninterestingVariables(boolean change) { + ArrayList allIntVars = new ArrayList(); // Set V + ArrayList newIntVars = new ArrayList(); // Set V'' + ArrayList intProc = new ArrayList(); // Processes with + // failure transitions or transitions that have interesting variables in + // their enabling conditions + for (String v : absProperty.getIntVars()) { + allIntVars.add(v); + newIntVars.add(v); + } + for (Transition t : transitions.values()) { + if (t.isFail()) { + intProc.add(process_trans.get(t)); + } + } + for (Transition t : transitions.values()) { + if (intProc.contains(process_trans.get(t)) + && t.getEnablingTree() != null) { + for (String u : t.getEnablingTree().getVars()) { + if (!allIntVars.contains(u)) { + allIntVars.add(u); + newIntVars.add(u); + } + } + } + if (intProc.contains(process_trans.get(t)) + && t.getDelayTree() != null) { + for (String u : t.getDelayTree().getVars()) { + if (!allIntVars.contains(u)) { + allIntVars.add(u); + newIntVars.add(u); + } + } + } + } + do { + for (Transition t : transitions.values()) { // Determine which + // processes are interesting + for (String v : newIntVars) { + if (t.containsAssignment(v)) { + if (!intProc.contains(process_trans.get(t))) { + intProc.add(process_trans.get(t)); + } + } + } + } + for (Transition t : transitions.values()) { + for (String key : t.getAssignTrees().keySet()) { + if (allIntVars.contains(key)) { + for (String v : t.getAssignTree(key).getVars()) { + if (!allIntVars.contains(v)) { + addInterestingVariable(v); + } + } + } + } + if (intProc.contains(process_trans.get(t)) + && t.getEnablingTree() != null) { + for (String v : t.getEnablingTree().getVars()) { + if (!allIntVars.contains(v)) { + addInterestingVariable(v); + } + } + } + if (intProc.contains(process_trans.get(t)) + && t.getDelayTree() != null) { + for (String v : t.getDelayTree().getVars()) { + if (!allIntVars.contains(v)) { + addInterestingVariable(v); + } + } + } + } + for (String v : allIntVars) { + if (newIntVars.contains(v)) { + newIntVars.remove(v); + } + } + for (String v : newestIntVars) { + if (!allIntVars.contains(v)) { + allIntVars.add(v); + newIntVars.add(v); + } + } + } while (newIntVars.size() > 0); + ArrayList removeVars = new ArrayList(); + for (Variable v : variables) { + if (!allIntVars.contains(v.getName())) { + removeVars.add(v); + change = true; + } + } + for (Variable v : removeVars) { + removeAllAssignVar(v.getName()); + removeVar(v.getName()); + } + return change; + } + + private boolean removeUninterestingTransitions(boolean change) { + ArrayList remove = new ArrayList(); + for (Transition t : transitions.values()) { + ArrayList visited = new ArrayList(); + if (!t.isInteresting(visited)) { + change = true; + for (Place p : t.getPreset()) { + removeMovement(p.getName(), t.getLabel()); + } + for (Place p : t.getPostset()) { + removeMovement(t.getLabel(), p.getName()); + } + remove.add(t); + } + } + for (Transition t : remove) { + removeTransition(t.getLabel()); + } + return change; + } + + private boolean simplifyExpr(boolean change) { + for (Transition t : transitions.values()) { + change = t.simplifyExpr(change); + } + return change; + } + + private boolean maxSimpExpr(boolean change) { + boolean temp_change; + do { + temp_change = false; + temp_change = simplifyExpr(temp_change); + temp_change = minimizeUniforms(temp_change); + if (temp_change) change = true; + } while (temp_change); + return change; + } + + private boolean minimizeUniforms(boolean change) { + for (Transition t : transitions.values()) { + change = t.minimizeUniforms(change); + } + return change; + } + + private void normalizeDelays() { + String N = new Integer(absProperty.getNormFactor()).toString(); + for (Transition t : transitions.values()) { + if (!t.containsDelay()) { + continue; + } + t.addDelay("uniform(floor(" + t.getDelay() + "/" + N + ")*" + N + + ",ceil(" + t.getDelay() + "/" + N + ")*" + N + ")"); + } + } + + private boolean removeTrans3(Transition transition) { + // Remove a transition with a single place in the postset + Place place = transition.getPostset()[0]; + Place[] preset = transition.getPreset(); + Transition[] postset = place.getPostset(); + Transition[] placePreset = place.getPreset(); + boolean marked = place.isMarked(); + // Check to make sure that the place is not a self-loop + if (preset.length == 1) { + Transition[] tempPreset = preset[0].getPreset(); + if (tempPreset.length == 1 && tempPreset[0].equals(transition)) { + return false; + } + } + if (transition.isFail()) { + return false; + } + // Update control flow + removeMovement(transition.getLabel(), place.getName()); + for (Place p : preset) { + if (marked) + p.setMarking(true); + removeMovement(p.getName(), transition.getLabel()); + for (Transition t : postset) { + addMovement(p.getName(), t.getLabel()); + } + } + for (Transition t : placePreset) { + removeMovement(t.getLabel(), place.getName()); + for (Place p : preset) { + if (!p.equals(place) && !t.equals(transition)) { + addMovement(t.getLabel(), p.getName()); + } + } + } + for (Transition t : postset) { + if (t.getEnablingTree() != null) { + ExprTree expr = t.getEnablingTree(); + if (transition.getEnablingTree() != null) { + expr.setNodeValues(expr, transition.getEnablingTree(), + "&&", 'l'); + t.addEnabling(expr.toString("LHPN")); + } + } else if (transition.getEnablingTree() != null) { + t.addEnabling(transition.getEnablingTree().toString()); + } + removeMovement(place.getName(), t.getLabel()); + } + removePlace(place.getName()); + // Add delays + String[] oldDelay = new String[2]; + Pattern rangePattern = Pattern.compile(RANGE); + if (transition.getDelay() != null) { + Matcher rangeMatcher = rangePattern.matcher(transition.getDelay()); + if (rangeMatcher.find()) { + oldDelay[0] = rangeMatcher.group(1); + oldDelay[1] = rangeMatcher.group(2); + } + } else { + oldDelay[0] = "0"; + oldDelay[1] = "inf"; + } + for (Transition t : postset) { + if (t.getDelay() != null) { + Matcher newMatcher = rangePattern.matcher(t.getDelay()); + if (newMatcher.find()) { + String newDelay[] = { newMatcher.group(1), + newMatcher.group(2) }; + for (int i = 0; i < newDelay.length; i++) { + if (!oldDelay[i].equals("inf") + && !newDelay[i].equals("inf")) { + if (i != 0 || !marked) { + newDelay[i] = String.valueOf(Integer + .parseInt(newDelay[i]) + + Integer.parseInt(oldDelay[i])); + } + } else { + newDelay[i] = "inf"; + } + } + t.addDelay("uniform(" + newDelay[0] + "," + newDelay[1] + + ")"); + } + } + } + removeTransition(transition.getLabel()); + return true; + } + + private boolean removeTrans4(Transition transition) { + // Remove a transition with a single place in the preset + Place place = transition.getPreset()[0]; + Transition[] preset = place.getPreset(); + Place[] postset = transition.getPostset(); + Transition[] placePostset = place.getPostset(); + // Check to make sure that the place is not a self-loop + if (postset.length == 1) { + Transition[] tempPostset = postset[0].getPostset(); + if (tempPostset.length == 1 && tempPostset[0].equals(transition)) { + return false; + } + } + if (transition.isFail()) { + return false; + } + boolean marked = place.isMarked(); + // Update the control Flow + removeMovement(place.getName(), transition.getLabel()); + for (Transition t : preset) { + removeMovement(t.getLabel(), place.getName()); + for (Place p : postset) { + addMovement(t.getLabel(), p.getName()); + } + } + for (Transition t : placePostset) { + removeMovement(place.getName(), t.getLabel()); + } + for (Place p : postset) { + removeMovement(transition.getLabel(), p.getName()); + for (Transition t : placePostset) { + if (!t.equals(transition)) { + addMovement(p.getName(), t.getLabel()); + } + } + if (marked) { + p.setMarking(true); + } + } + // Add delays + String[] oldDelay = new String[2]; + Pattern rangePattern = Pattern.compile(RANGE); + Matcher rangeMatcher = rangePattern.matcher(transition.getDelay()); + if (rangeMatcher.find()) { + oldDelay[0] = rangeMatcher.group(1); + oldDelay[1] = rangeMatcher.group(2); + } + HashMap postTrans = new HashMap(); + for (Place p : postset) { + for (Transition t : p.getPostset()) { + postTrans.put(t, p.isMarked()); + } + } + for (Transition t : postTrans.keySet()) { + if (t.getDelay() != null) { + Matcher newMatcher = rangePattern.matcher(t.getDelay()); + if (newMatcher.find()) { + String newDelay[] = { newMatcher.group(1), + newMatcher.group(2) }; + for (int i = 0; i < newDelay.length; i++) { + if (!oldDelay[i].equals("inf") + && !newDelay[i].equals("inf")) { + newDelay[i] = String.valueOf(Integer + .parseInt(newDelay[i]) + + Integer.parseInt(oldDelay[i])); + } else { + newDelay[i] = "inf"; + } + } + t.addDelay("uniform(" + newDelay[0] + "," + newDelay[1] + + ")"); + } + } + } + removePlace(place.getName()); + removeTransition(transition.getLabel()); + return true; + } + + private boolean removeVacTrans(Transition transition) { + Place place = transition.getPostset()[0]; + Place[] preset = transition.getPreset(); + Transition[] postset = place.getPostset(); + Transition[] placePreset = place.getPreset(); + boolean marked = place.isMarked(); + // Check to make sure that the place is not a self-loop + if (preset.length == 1) { + Transition[] tempPreset = preset[0].getPreset(); + if (tempPreset.length == 1 && tempPreset[0].equals(transition)) { + return false; + } + } + if (transition.isFail()) { + return false; + } + // Update control flow + removeMovement(transition.getLabel(), place.getName()); + for (Place p : preset) { + places.put(p.getName(), p); + if (marked) + p.setMarking(true); + removeMovement(p.getName(), transition.getLabel()); + for (Transition t : postset) { + addMovement(p.getName(), t.getLabel()); + } + } + for (Transition t : placePreset) { + removeMovement(t.getLabel(), place.getName()); + for (Place p : preset) { + if (!p.equals(place) && !t.equals(transition)) { + addMovement(t.getLabel(), p.getName()); + } + } + } + for (Transition t : postset) { + if (t.getEnablingTree() != null) { + ExprTree expr = t.getEnablingTree(); + if (transition.getEnablingTree() != null) { + expr.setNodeValues(expr, transition.getEnablingTree(), + "&&", 'l'); + t.addEnabling(expr.toString("LHPN")); + } + } else if (transition.getEnablingTree() != null) { + t.addEnabling(transition.getEnablingTree().toString("LHPN")); + } + removeMovement(place.getName(), t.getLabel()); + } + removePlace(place.getName()); + // Add delays + String[] oldDelay = new String[2]; + Pattern rangePattern = Pattern.compile(RANGE); + if (transition.getDelay() != null) { + Matcher rangeMatcher = rangePattern.matcher(transition.getDelay()); + if (rangeMatcher.find()) { + oldDelay[0] = rangeMatcher.group(1); + oldDelay[1] = rangeMatcher.group(2); + } + } else { + oldDelay[0] = "0"; + oldDelay[1] = "inf"; + } + for (Transition t : postset) { + t.addDelay(transition.getDelay() + "+" + t.getDelay()); + } + removeTransition(transition.getLabel()); + return true; + } + + private boolean removeVacTransAbs(Transition transition) { + Place place = transition.getPostset()[0]; + Place[] preset = transition.getPreset(); + Transition[] postset = place.getPostset(); + Transition[] placePreset = place.getPreset(); + boolean marked = place.isMarked(); + // Check to make sure that the place is not a self-loop + if (preset.length == 1) { + Transition[] tempPreset = preset[0].getPreset(); + if (tempPreset.length == 1 && tempPreset[0].equals(transition)) { + return false; + } + } + if (transition.isFail()) { + return false; + } + // Update control flow + removeMovement(transition.getLabel(), place.getName()); + for (Place p : preset) { + if (marked) + addPlace(p.getName(), true); + removeMovement(p.getName(), transition.getLabel()); + for (Transition t : postset) { + addMovement(p.getName(), t.getLabel()); + } + } + for (Transition t : placePreset) { + removeMovement(t.getLabel(), place.getName()); + for (Place p : preset) { + if (!p.equals(place) && !t.equals(transition)) { + addMovement(t.getLabel(), p.getName()); + } + } + } + for (Transition t : postset) { + if (t.getEnablingTree() != null) { + ExprTree expr = t.getEnablingTree(); + if (transition.getEnablingTree() != null) { + expr.setNodeValues(expr, transition.getEnablingTree(), + "&&", 'l'); + t.addEnabling(expr.toString("LHPN")); + } + } else if (transition.getEnablingTree() != null) { + t.addEnabling(transition.getEnabling()); + } + removeMovement(place.getName(), t.getLabel()); + } + removePlace(place.getName()); + // Add delays + String oldDelay = new String(); + if (transition.getDelay() != null) { + oldDelay = transition.getDelay(); + } + for (Transition t : postset) { + if (t.getDelay() != null) { + String newDelay = t.getDelay() + "+" + oldDelay; + t.addDelay("uniform(" + oldDelay + "," + newDelay + + ")"); + } + } + removeTransition(transition.getLabel()); + return true; + } + + private void combineTransitions(Transition trans1, Transition trans2, + boolean samePreset, boolean samePostset) { + if (trans2.isFail() || !transitions.containsValue(trans1)) { + return; + } + if (trans1.containsDelay() && trans2.containsDelay()) { + String[] delay = { trans1.getDelay(), trans2.getDelay() }; + for (int i = 0; i < delay.length; i++) { + trans1.addDelay("uniform(min(" + delay[0] + "," + delay[1] + + ")," + delay[0] + "+" + delay[1] + ")"); + } + } else { + trans1.addDelay("uniform(0,inf)"); + } + // Combine Control Flow + for (Place p : trans2.getPreset()) { + addMovement(p.getName(), trans1.getLabel()); + removeMovement(p.getName(), trans2.getLabel()); + } + for (Place p : trans2.getPostset()) { + addMovement(trans1.getLabel(), p.getName()); + removeMovement(trans2.getLabel(), p.getName()); + } + removeTransition(trans2.getLabel()); + if (!samePostset) { + for (Place p : trans2.getPostset()) { + if (p.isMarked() == trans1.getPostset()[0].isMarked()) { + combinePlaces(p, trans1.getPostset()[0]); + } + } + } else if (!samePreset) { + for (Place p : trans2.getPreset()) { + if (p.isMarked() == trans1.getPreset()[0].isMarked()) { + combinePlaces(p, trans1.getPreset()[0]); + } + } + } + } + + private boolean propagateConst(boolean change) { + for (String v : booleans.keySet()) { + if (!booleans.get(v).getInitValue().equals("unknown")) { + boolean unassigned = true; + for (Transition t : transitions.values()) { + if (t.getBoolAssignments().containsKey(v)) { + unassigned = false; + } + } + if (unassigned) { + change = true; + ExprTree init = new ExprTree(this); + init.token = init.intexpr_gettok(booleans.get(v) + .getInitValue()); + init.intexpr_L(booleans.get(v).getInitValue()); + for (Transition t : transitions.values()) { + if (t.getEnablingTree() != null) { + t.getEnablingTree().replace(v, "boolean", init); + } + if (t.getDelayTree() != null) { + t.getDelayTree().replace(v, "boolean", init); + } + for (ExprTree e : t.getAssignTrees().values()) { + if (e != null) { + e.replace(v, "boolean", init); + } + } + } + } + } + } + for (String v : continuous.keySet()) { + if (!continuous.get(v).getInitValue().equals("[-inf,inf]")) { + Pattern pattern = Pattern + .compile("\\[([\\d\\.-]+?),([\\d\\.-]+?)\\]"); + Matcher valMatch = pattern.matcher(continuous.get(v) + .getInitValue()); + Matcher rateMatch = pattern.matcher(continuous.get(v) + .getInitRate()); + Double value = 0.0; + if (valMatch.find()) { + Double lval = Double.parseDouble(valMatch.group(1)); + Double uval = Double.parseDouble(valMatch.group(2)); + if (!lval.equals(uval)) { + continue; + } + value = lval; + } else { + value = Double + .parseDouble(continuous.get(v).getInitValue()); + } + if (rateMatch.find()) { + Double lval = Double.parseDouble(rateMatch.group(1)); + Double uval = Double.parseDouble(rateMatch.group(2)); + if (!lval.equals(0.0) || !uval.equals(0.0)) { + continue; + } + } + boolean unassigned = true; + for (Transition t : transitions.values()) { + if (t.getAssignments().containsKey(v)) { + unassigned = false; + } + } + if (unassigned) { + change = true; + ExprTree init = new ExprTree(this); + init.token = init.intexpr_gettok(value.toString()); + init.intexpr_L(value.toString()); + for (Transition t : transitions.values()) { + if (t.getEnablingTree() != null) { + t.getEnablingTree().replace(v, "continuous", init); + } + if (t.getDelayTree() != null) { + t.getDelayTree().replace(v, "continuous", init); + } + for (ExprTree e : t.getAssignTrees().values()) { + if (e != null) { + e.replace(v, "continuous", init); + } + } + } + } + } + } + for (String v : integers.keySet()) { + if (!integers.get(v).getInitValue().equals("[-inf,inf]")) { + Pattern pattern = Pattern + .compile("\\[([\\d\\.-]+?),([\\d\\.-]+?)\\]"); + Matcher valMatch = pattern.matcher(integers.get(v) + .getInitValue()); + Double value = 0.0; + if (valMatch.find()) { + Double lval = Double.parseDouble(valMatch.group(1)); + Double uval = Double.parseDouble(valMatch.group(2)); + if (!lval.equals(uval)) { + continue; + } + value = lval; + } else { + value = Double.parseDouble(integers.get(v).getInitValue()); + } + boolean unassigned = true; + for (Transition t : transitions.values()) { + if (t.getIntAssignments().containsKey(v)) { + unassigned = false; + } + } + if (unassigned) { + change = true; + ExprTree init = new ExprTree(this); + init.token = init.intexpr_gettok(value.toString()); + init.intexpr_L(value.toString()); + for (Transition t : transitions.values()) { + if (t.getEnablingTree() != null) { + t.getEnablingTree().replace(v, "integer", init); + } + if (t.getDelayTree() != null) { + t.getDelayTree().replace(v, "integer", init); + } + for (ExprTree e : t.getAssignTrees().values()) { + if (e != null) { + e.replace(v, "integer", init); + } + } + } + } + } + } + return change; + } + + private boolean trans8Iteration(Transition trans, + ArrayList unvisited, boolean change) { + ArrayList toChange = new ArrayList(); + for (String var : trans.getIntAssignments().keySet()) { + String[] add = { trans.getLabel(), var }; + toChange.add(add); + } + for (String var : trans.getBoolAssignments().keySet()) { + String[] add = { trans.getLabel(), var }; + toChange.add(add); + } + for (String[] array : toChange) { + change = trans8(array[0], array[1], change); + } + unvisited.remove(trans); + for (Place p : trans.getPostset()) { + for (Transition t : p.getPostset()) { + if (unvisited.contains(t)) { + change = trans8Iteration(t, unvisited, change); + unvisited.remove(t); + } + } + } + return change; + } + + private boolean trans8(String transName, String var, boolean change) { + // Propagate expressions of local variables to transition post sets + Transition trans = transitions.get(transName); + if (!((process_read.get(var).equals(process_trans.get(trans)) || process_read + .get(var) == 0) && process_write.get(var).equals( + process_trans.get(trans)))) { + return change; // Return if the variable is not local + } + if (intVars.contains(var)) { + return change; + } + HashMap typeAssign; + // The assignments that will contain var + if (isInteger(var)) { + typeAssign = trans.getIntAssignTrees(); + } else if (isBoolean(var)) { + typeAssign = trans.getBoolAssignTrees(); + } else { + return change; + } + ExprTree e = typeAssign.get(var); + if (e == null) { + return change; + } + for (String v : e.getVars()) { + if (!process_write.get(v).equals(process_trans.get(trans))) { + return change; // Return if the variables in support(e) are + // not locally written + } + } + if (e.toString().equals("")) { + return change; + } + for (Place p : trans.getPostset()) { + if (p.isMarked()) + return change; + for (Transition tP : p.getPostset()) { + if (transName.equals(tP.getLabel())) { + return change; + } + for (Place pP : tP.getPreset()) { + for (Transition tPP : pP.getPreset()) { + if (tPP.getAssignTrees().containsKey(var)) { + ExprTree ePP = tPP.getAssignTree(var); + if (!ePP.isEqual(e)) { + return change; // All assignments + // to var in ..(t..) must be equal + } + for (String v : ePP.getVars()) { + if (!v.equals(var)) { + if (isBoolean(v)) { // All + // variables in + // support(e) cannot be + // assigned + if (tPP.getBoolAssignments() + .containsKey(v)) { + return change; + } + } else if (isInteger(v)) { + if (tPP.getIntAssignments() + .containsKey(v)) { + return change; + } + } else { + if (tPP.getContAssignments() + .containsKey(v)) { + return change; + } + } + } + } + } else { + return change; + } + } + } + } + } + // Perform transform + for (Place p : trans.getPostset()) { + for (Transition tP : p.getPostset()) { + replace(tP, var, e); + for (Place pP : tP.getPreset()) { + for (Transition tPP : pP.getPreset()) { + if (isBoolean(var)) { + tPP.removeBoolAssign(var); + } else if (isInteger(var)) { + tPP.removeIntAssign(var); + } else { + tPP.removeContAssign(var); + } + } + } + change = true; + } + } + return change; + } + + private boolean readBeforeWrite(Transition trans, String var) { + for (Place p : trans.getPostset()) { + for (Transition t : p.getPostset()) { + boolean written = false; + for (String s : t.getAssignTrees().keySet()) { + ExprTree e1 = t.getAssignTree(s); + if (e1.getVars().contains(var)) { + return true; + } + if (s.equals(var)) { + written = true; + } + } + if (t.getEnablingTree() != null) { + if (t.getEnablingTree().getVars().contains(var)) { + return true; + } + } + if (written) + return false; + if (!read.contains(t)) { + read.add(t); + if (readBeforeWrite(t, var)) { + return true; + } + } + } + } + return false; + } + + private static boolean weakReadBeforeWrite(Transition trans, String var) { + for (Place p : trans.getPostset()) { + for (Transition t : p.getPostset()) { + boolean written = false; + for (String s : t.getAssignTrees().keySet()) { + ExprTree e1 = t.getAssignTree(s); + if (e1.getVars().contains(var)) { + return true; + } + if (s.equals(var)) { + written = true; + } + } + if (t.getEnablingTree() != null) { + if (t.getEnablingTree().getVars().contains(var)) { + return true; + } + } + if (written) + return false; + } + } + return true; + } + + private boolean removeDanglingTransitions(boolean change) { + ArrayList remove = new ArrayList(); + for (Transition t : transitions.values()) { + if (t.getPostset().length == 0) { + if (t.getAssignments().size() == 0) { + if (!t.isFail()) { + for (Place p : t.getPreset()) { + if (p.getPostset().length > 1) { + return change; + } + } + remove.add(t); + } + } + } + } + for (Transition t : remove) { + for (Place p : t.getPreset()) { + for (Transition tP : p.getPreset()) { + removeMovement(tP.getLabel(), p.getName()); + } + removeMovement(p.getName(), t.getLabel()); + removePlace(p.getName()); + } + removeTransition(t.getLabel()); + change = true; + } + return change; + } + + private boolean divideProcesses() { + for (Transition t : transitions.values()) { // Add all transitions to + // process structure + process_trans.put(t, 0); + } + for (String v : booleans.keySet()) { // / Add All variables to process + // structure + process_write.put(v, 0); + process_read.put(v, 0); + } + for (String v : continuous.keySet()) { + process_write.put(v, 0); + process_read.put(v, 0); + } + for (String v : integers.keySet()) { + process_write.put(v, 0); + process_read.put(v, 0); + } + Integer i = 1; // The total number of processes + Integer process = 1; // The active process number + while (process_trans.containsValue(0)) { + Transition new_proc = new Transition(); // Find a transition that is + // not part of a process + for (Transition t : process_trans.keySet()) { + if (process_trans.get(t) != null && process_trans.get(t) == 0) { + new_proc = t; + break; + } + } + boolean flag = false; // Make sure that it is not part of a process + for (Place p : new_proc.getPreset()) { + if (!flag) // Check the preset to see if it is part of a process + for (Transition t : p.getPreset()) { + if (!flag) + if (process_trans.get(t) != null && process_trans.get(t) != 0) { + flag = true; + process = process_trans.get(t); + break; + } + } + } + if (!flag) // Check the postset to see if it is part of a process + for (Place p : new_proc.getPostset()) { + if (!flag) + for (Transition t : p.getPostset()) { + if (!flag) + if (process_trans.get(t) != 0) { + flag = true; + process = process_trans.get(t); + break; + } + } + } + if (!flag) { + i++; // Increment the process counter if it is not part of a + // process + process = i; + } + if (!addTransProcess(new_proc, process)) + return false; + } + assignVariableProcess(); + return true; + } + + /** + * This method walks on an LPN and decomposes the LPN into processes. + * Each process is a strongly connected places and transitions. + * @return + */ + public boolean decomposeLpnIntoProcesses() { + // Add all transitions to process structure + for (Transition t : transitions.values()) { + process_trans.put(t, 0); + } + Integer i = 1; // The total number of processes + Integer process = 1; // The active process number + while (process_trans.containsValue(0)) { + Transition new_proc = new Transition(); // Find a transition that is not part of a process. + for (Transition t : process_trans.keySet()) { + if (process_trans.get(t) == 0) { + new_proc = t; + break; + } + } + boolean flag = false; // Make sure that it is not part of a process + for (Place p : new_proc.getPreset()) { + if (!flag) // Check the preset to see if it is part of a process + if (p.getPreset().length == 0) { + if (new_proc.hasConflict()) { + for (Transition conflict : new_proc.getConflictSet()) { + if (process_trans.get(conflict) != 0) { + flag = true; + process = process_trans.get(conflict); + break; + } + } + } + } + else { + for (Transition t : p.getPreset()) { + if (!flag) + if (process_trans.get(t) != 0) { + flag = true; + process = process_trans.get(t); + break; + } + if (process_trans.get(t) == 0 && t.hasConflict()) { + for (Transition conflict : t.getConflictSet()) { + if (process_trans.get(conflict) != 0) { + flag = true; + process = process_trans.get(conflict); + break; + } + } + } + } + } + + } + if (!flag) // Check the postset to see if it is part of a process + for (Place p : new_proc.getPostset()) { + if (!flag) + for (Transition t : p.getPostset()) { + if (!flag) + if (process_trans.get(t) != 0) { + flag = true; + process = process_trans.get(t); + break; + } + } + } + if (!flag) { + i++; // Increment the process counter if it is not part of a + // process + process = i; + } + if (!addTransProcess(new_proc, process)) + return false; + } + assignProcessesToVariables(); + return true; + } + + public HashMap getTransWithProcIDs() { + return process_trans; + } + + public HashMap> getProcessRead() { + return processReadVar; + } + + public HashMap> getProcessWrite() { + return processWriteToVar; + } + + public void assignVariableProcess() { + for (Transition t : transitions.values()) { // For each + // transition with assignments + HashMap assignments = t.getAssignments(); + HashMap assignTrees = t.getAssignTrees(); + for (String v : assignments.keySet()) { // The variables assigned on + // each transition + if ((process_write.get(v) == 0) + || (process_write.get(v) == process_trans.get(t))) { + process_write.put(v, process_trans.get(t)); // Mark a + // variable as locally written to a process + } else { + process_write.put(v, -1); // Mark a variable as globally + // written + } + } + for (ExprTree e : assignTrees.values()) { + for (String v : e.getVars()) { + if ((process_read.get(v) == 0) + || (process_read.get(v) == process_trans.get(t))) { + process_read.put(v, process_trans.get(t)); // Mark + // a variable as locally read + } else { + process_read.put(v, -1); // Mark a variable as + // globally read + } + } + } + ExprTree e = t.getEnablingTree(); + if (e != null) { + for (String v : e.getVars()) { + if ((process_read.get(v) == 0) + || (process_read.get(v) == process_trans.get(t))) { + process_read.put(v, process_trans.get(t)); + } else { + process_read.put(v, -1); + } + } + } + } + } + + // This method uses process_trans constructed by decomposeLpnIntoProcesses(). + public void assignProcessesToVariables() { + for (String v : booleans.keySet()) { // Add All variables to process structure + processWriteToVar.put(v, new ArrayList()); + processReadVar.put(v, new ArrayList()); + } + for (String v : continuous.keySet()) { + processWriteToVar.put(v, new ArrayList()); + processReadVar.put(v, new ArrayList()); + } + for (String v : integers.keySet()) { + processWriteToVar.put(v, new ArrayList()); + processReadVar.put(v, new ArrayList()); + } + + for (Transition t : transitions.values()) { + HashMap assignments = t.getAssignments(); + HashMap assignTrees = t.getAssignTrees(); + for (String v : assignments.keySet()) { + // Variables assigned on each transition + ArrayList processIDSet = processWriteToVar.get(v); + processIDSet.add(process_trans.get(t)); + processWriteToVar.put(v, processIDSet); + } +// for (String v : assignments.keySet()) { +// // Variables assigned on each transition +// if ((processWrite.get(v).isEmpty()) +// || (processWrite.get(v).size() == 1 +// && processWrite.get(v).get(0).equals(process_trans.get(t)))) { +// ArrayList processIDSet = new ArrayList(1); +// processIDSet.add(process_trans.get(t)); +// processWrite.put(v, processIDSet); +// // variable locally written to a process +// } else { +// ArrayList processIDSet = processWrite.get(v); +// processIDSet.add(process_trans.get(t)); +// processWrite.put(v, processIDSet); +// //variable as globally written +// } +// } + for (ExprTree e : assignTrees.values()) { + for (String v : e.getVars()) { + ArrayList processIDSet = processReadVar.get(v); + processIDSet.add(process_trans.get(t)); + processReadVar.put(v, processIDSet); + } + } +// for (ExprTree e : assignTrees.values()) { +// for (String v : e.getVars()) { +// if ((processRead.get(v).isEmpty()) +// || (processRead.get(v).size() == 1 +// && processRead.get(v).get(0).equals(process_trans.get(t)))) { +// ArrayList processIDSet = new ArrayList(1); +// processIDSet.add(process_trans.get(t)); +// processRead.put(v, processIDSet); +// // variable locally read +// } else { +// ArrayList processIDSet = processRead.get(v); +// processIDSet.add(process_trans.get(t)); +// processRead.put(v, processIDSet); +// // variable globally read +// } +// } +// } + ExprTree e = t.getEnablingTree(); + if (e != null) { + for (String v : e.getVars()) { + ArrayList processIDSet = processReadVar.get(v); + processIDSet.add(process_trans.get(t)); + processReadVar.put(v, processIDSet); + } + } +// if (e != null) { +// for (String v : e.getVars()) { +// if ((processRead.get(v).isEmpty()) +// || (processRead.get(v).size() == 1 +// && (processRead.get(v).get(0).equals(process_trans.get(t))))) { +// ArrayList processIDSet = new ArrayList(); +// processIDSet.add(process_trans.get(t)); +// processRead.put(v, processIDSet); +// // variable locally read +// } else { +// ArrayList processIDSet = processRead.get(v); +// processIDSet.add(process_trans.get(t)); +// processRead.put(v, processIDSet); +// // variable globally read +// } +// } +// } + ExprTree delayTree = t.getDelayTree(); + if (delayTree != null) { + for (String v : delayTree.getVars()) { + ArrayList processIDSet = processReadVar.get(v); + processIDSet.add(process_trans.get(t)); + processReadVar.put(v, processIDSet); + } + } + } + } + + public boolean addTransProcess(Transition tran, Integer proc) { + process_trans.put(tran, proc); // Add the current transition to the process + for (Place p : tran.getPostset()) { + for (Transition t : p.getPostset()) { + if (process_trans.get(t) == 0) + addTransProcess(t, proc); // Add the postset of the transition to the same process recursively + else if (process_trans.get(t) != proc) { + System.out + .println("Error: Multiple Process Labels Added to the Same Transition"); + return false; + } + } + } + for (Place p : tran.getPreset()) { + if (p.getPreset().length == 0) { + if (tran.hasConflict()) { + for (Transition conflict : tran.getConflictSet()) { + if (process_trans.get(conflict) != 0 && process_trans.get(conflict) != proc) { + System.out + .println("Error: Conflicting transitions are labeled as different process transitions."); + return false; + } + if (process_trans.get(conflict) == 0) { + addTransProcess(conflict, proc); + } + } + } + } + else { + for (Transition t : p.getPreset()) { + if (process_trans.get(t) == 0) + if (!t.hasConflict()) + addTransProcess(t, proc); // Add the preset of the transition to the same process recursively + else { + for (Transition conflict : tran.getConflictSet()) { + if (process_trans.get(conflict) != 0 && process_trans.get(conflict) != proc) { + System.out + .println("Error: Conflicting transitions are labeled as different process transitions."); + return false; + } + if (process_trans.get(conflict) == 0) { + addTransProcess(conflict, proc); + } + } + } + else if (process_trans.get(t) != proc) { + System.out + .println("Error: Multiple Process Labels Added to the Same Transition"); + return false; + } + } + } + } + return true; + } + + // Oridiginal version. It assigns conflicting transitions with more than 1 process IDs (incorrect). +// public boolean addTransProcess(Transition trans, Integer proc) { +// process_trans.put(trans, proc); // Add the current transition to the +// // process +// for (Place p : trans.getPostset()) { +// for (Transition t : p.getPostset()) { +// if (process_trans.get(t) == 0) +// addTransProcess(t, proc); // Add the postset of the +// // transition to the same process recursively +// else if (process_trans.get(t) != proc) { +// System.out +// .println("Error: Multiple Process Labels Added to the Same Transition"); +// return false; +// } +// } +// } +// for (Place p : trans.getPreset()) { +// for (Transition t : p.getPreset()) { +// if (process_trans.get(t) == 0) +// addTransProcess(t, proc); // Add the preset of the +// // transition to the same process recursively +// else if (process_trans.get(t) != proc) { +// System.out +// .println("Error: Multiple Process Labels Added to the Same Transition"); +// return false; +// } +// } +// } +// return true; +// } + + private boolean replace(Transition trans, String var, ExprTree expr) { + boolean flag = false; + String type; + if (isInteger(var)) { + type = "integer"; + } else if (isContinuous(var)) { + type = "continuous"; + } else { + type = "boolean"; + } + if (trans.getEnablingTree() != null) { + trans.getEnablingTree().replace(var, type, expr); + trans.addEnabling(trans.getEnablingTree().toString("LHPN")); + flag = true; + } + if (trans.getDelayTree() != null) { + trans.getDelayTree().replace(var, type, expr); + trans.addDelay(trans.getDelayTree().toString("LHPN")); + flag = true; + } + for (String v : trans.getAssignTrees().keySet()) { + ExprTree e1 = trans.getAssignTree(v); + if (e1 != null) { + e1.replace(var, type, expr); + if (isBoolean(v)) { + trans.addBoolAssign(v, e1.toString("boolean", "LHPN")); + } else if (isInteger(v)) { + trans.addIntAssign(v, e1.toString("integer", "LHPN")); + } else if (isContinuous(v) + && trans.getContAssignments().containsKey(var)) { + trans.addContAssign(v, e1.toString("continuous", "LHPN")); + } else if (trans.getRateAssignments().containsKey(var)) { + trans.addRateAssign(v, e1.toString("continuous", "LHPN")); + } else { + trans.addRateAssign(v.split("\\s")[0], e1.toString( + "continuous", "LHPN")); + } + } + } + if (isInteger(var)) { + if (!trans.getIntAssignments().containsKey(var)) { + trans.addIntAssign(var, expr.toString()); + } + } else if (isBoolean(var)) { + if (!trans.getBoolAssignments().containsKey(var)) { + trans.addBoolAssign(var, expr.toString()); + } + } + return flag; + } + + private boolean areCorrelatedBooleans(String var1, String var2) { + String init1; + String init2; + init1 = booleans.get(var1).getInitValue(); + init2 = booleans.get(var2).getInitValue(); + if (init1.equals(init2)) { + for (Transition t : transitions.values()) { + if (t.getBoolAssignments().containsKey(var1)) { + if (t.getBoolAssignments().containsKey(var2)) { + if (!t.getBoolAssignments().get(var1).equals( + t.getBoolAssignments().get(var2))) { + return false; + } + } else { + return false; + } + } else if (t.containsAssignment(var2)) { + return false; + } + } + } else { + return false; + } + return true; + } + + private boolean areInverted(String var1, String var2) { + String init1; + String init2; + init1 = booleans.get(var1).getInitValue(); + init2 = booleans.get(var2).getInitValue(); + if (!(init1.equals("~(" + init2 + ")") || init1.equals("unknown") + && init2.equals("unknown"))) { + return false; + } + for (Transition t : transitions.values()) { + if (t.getBoolAssignments().containsKey(var1)) { + if (t.getBoolAssignments().containsKey(var2)) { + ExprTree expr = new ExprTree(t.getBoolAssignTree(var2)); + expr.setNodeValues(expr, null, "!", 'l'); + if (t.getBoolAssignTree(var2).equals(expr)) { + continue; + } else if (t.getBoolAssignment(var1).toLowerCase().equals( + "true") + && t.getBoolAssignment(var2).toLowerCase().equals( + "false") + || t.getBoolAssignment(var1).toLowerCase().equals( + "false") + && t.getBoolAssignment(var2).toLowerCase().equals( + "true")) { + continue; + } else { + return false; + } + } + return false; + } else if (t.containsAssignment(var2)) { + return false; + } + } + return true; + } + + private boolean areCorrelatedContinuous(String var1, String var2) { + if (continuous.get(var1).equals(continuous.get(var2))) { + for (Transition t : transitions.values()) { + if (t.getContAssignTrees().containsKey(var1)) { + if (t.getContAssignTrees().containsKey(var2)) { + if (!t.getContAssignTree(var1).equals( + t.getContAssignTree(var2))) { + return false; + } + } else { + return false; + } + } else if (t.getContAssignments().containsKey(var2)) { + return false; + } + } + } + return true; + } + + private boolean areCorrelatedIntegers(String var1, String var2) { + if (integers.get(var1).equals(integers.get(var2))) { + for (Transition t : transitions.values()) { + if (t.getIntAssignTrees().containsKey(var1)) { + if (t.getIntAssignTrees().containsKey(var2)) { + if (!t.getIntAssignment(var1).equals( + t.getIntAssignment(var2))) { + return false; + } + } else { + return false; + } + } else if (t.getIntAssignTrees().containsKey(var2)) { + return false; + } + } + } else { + return false; + } + return true; + } + + private void mergeVariables(String var1, String var2) { + Variable v1 = getVariable(var1); + Variable v2 = getVariable(var2); + if (!variables.contains(v2) || !variables.contains(v1)) { + return; + } + for (Transition t : transitions.values()) { + if (t.getEnablingTree() != null) { + t.getEnablingTree().replaceVar(var2, var1); + } + if (t.getDelayTree() != null) { + t.getDelayTree().replaceVar(var2, var1); + } + HashMap m = t.getBoolAssignTrees(); + for (ExprTree e : m.values()) { + if (e != null) { + e.replaceVar(var2, var1); + } + } + if (m.containsKey(var2)) { + m.remove(var2); + t.removeBoolAssign(var2); + } + m = t.getContAssignTrees(); + for (ExprTree e : m.values()) { + if (e != null) { + e.replaceVar(var2, var1); + } + } + if (m.containsKey(var2)) { + m.remove(var2); + t.removeContAssign(var2); + } + m = t.getBoolAssignTrees(); + for (ExprTree e : m.values()) { + if (e != null) { + e.replaceVar(var2, var1); + } + } + if (m.containsKey(var2)) { + m.remove(var2); + t.removeIntAssign(var2); + } + m = t.getRateAssignTrees(); + for (ExprTree e : m.values()) { + if (e != null) { + e.replaceVar(var2, var1); + } + } + if (m.containsKey(var2)) { + m.remove(var2); + t.removeRateAssign(var2); + } + t.simplifyExpr(false); + } + if (process_read.get(var1) != process_read.get(var2)) { + process_read.put(var1, -1); + } + removeVar(var2); + } + + private void mergeVariables(ExprTree expr, String var2) { + Variable v1 = getVariable(expr.r1.variable); + Variable v2 = getVariable(var2); + if (!variables.contains(v2) || !variables.contains(v1)) { + return; + } + for (Transition t : transitions.values()) { + if (t.getEnablingTree() != null) { + t.getEnablingTree().replace(var2, "", expr); + } + HashMap m = t.getBoolAssignTrees(); + for (ExprTree e : m.values()) { + if (e != null) { + e.replace(var2, "", expr); + } + } + if (m.containsKey(var2)) { + m.remove(var2); + t.removeBoolAssign(var2); + } + m = t.getContAssignTrees(); + for (ExprTree e : m.values()) { + if (e != null) { + e.replace(var2, "", expr); + } + } + if (m.containsKey(var2)) { + m.remove(var2); + t.removeContAssign(var2); + } + m = t.getIntAssignTrees(); + for (ExprTree e : m.values()) { + if (e != null) { + e.replace(var2, "", expr); + } + } + if (m.containsKey(var2)) { + m.remove(var2); + t.removeIntAssign(var2); + } + m = t.getRateAssignTrees(); + for (ExprTree e : m.values()) { + if (e != null) { + e.replace(var2, "", expr); + } + } + if (m.containsKey(var2)) { + m.remove(var2); + t.removeRateAssign(var2); + } + } + if (process_read.get(expr.r1.variable) != process_read.get(var2)) { + process_read.put(expr.r1.variable, -1); + } + removeVar(var2); + } + + public boolean mergeTransitionsSimp(boolean change, boolean checkEnabling) { + HashMap> toMerge = new HashMap>(); + for (Transition t1 : transitions.values()) { + for (Transition t2 : transitions.values()) { + if (t1.equals(t2)) { + continue; + } + if (t1.isFail() != t2.isFail()) { + continue; + } + if ((comparePreset(t1, t2) || (t1.getPreset().length == 0 && t2 + .getPreset().length == 0)) + && (comparePostset(t1, t2) || (t1.getPostset().length == 0 && t2 + .getPostset().length == 0)) + && (t1.getEnablingTree() != null && t2 + .getEnablingTree() != null)) { + boolean combine = true; + if (checkEnabling) { + ExprTree tree = new ExprTree(this); + tree.setNodeValues(t1.getEnablingTree(), t2 + .getEnablingTree(), "&&", 'l'); + for (String v : tree.getVars()) { + if (process_write.get(v) != 0 + && process_write.get(v) != process_trans + .get(t1)) { + combine = false; + break; + } + } + if (!combine) + continue; + for (Transition t : transitions.values()) { + if (tree.getChange(t.getAssignments()) != 'F' + && tree.getChange(t.getAssignments()) != 'f' + && tree.getChange(t.getAssignments()) != 'U') { + combine = false; + break; + } + } + if (!combine) + continue; + if (toMerge.containsKey(t1)) { + for (Transition t3 : toMerge.get(t1)) { + ExprTree tree3 = new ExprTree(this); + tree3.setNodeValues(t3.getEnablingTree(), t2 + .getEnablingTree(), "&&", 'l'); + for (Transition t : transitions.values()) { + if (tree3.becomesTrue(t.getAssignments())) { + combine = false; + break; + } + } + } + } + if (!combine) + continue; + for (String var : t1.getAssignments().keySet()) { + if (!t2.containsAssignment(var) + || !t1.getAssignTree(var).isEqual( + t2.getAssignTree(var))) { + combine = false; + break; + } + } + if (!combine) + continue; + for (String var : t2.getAssignments().keySet()) { + if (!t1.containsAssignment(var)) { + combine = false; + break; + } + } + if (!combine) + continue; + } + if (combine) { + if (toMerge.containsKey(t1)) { + toMerge.get(t1).add(t2); + } else { + toMerge.put(t1, new ArrayList()); + toMerge.get(t1).add(t2); + } + } + } + } + } + for (Transition t : toMerge.keySet()) { + if (transitions.containsValue(t)) { + mergeTransitions(t, toMerge.get(t), false); + change = true; + } + } + return change; + } + + private boolean mergeTransitionsAbs(boolean change) { + HashMap> toMerge = new HashMap>(); + for (Transition t1 : transitions.values()) { + for (Transition t2 : transitions.values()) { + if (t1.equals(t2)) { + continue; + } + if (t1.isFail() != t2.isFail()) { + continue; + } + if (!t1.isPersistent() || !t2.isPersistent()) { + continue; + } + if (toMerge.containsKey(t1)) { + toMerge.get(t1).add(t2); + } else { + toMerge.put(t1, new ArrayList()); + toMerge.get(t1).add(t2); + } + } + } + for (Transition t : toMerge.keySet()) { + if (transitions.containsValue(t)) { + mergeTransitions(t, toMerge.get(t), true); + change = true; + } + } + return change; + } + + private void mergeTransitions(Transition t, ArrayList list, + boolean abstraction) { + if (abstraction) { + for (Transition tP : list) { + if (!transitions.containsKey(tP.getLabel())) { + return; + } + } + String enabling = "(" + t.getEnabling() + ")"; + for (Transition tP : list) { + enabling = enabling + "|(" + tP.getEnabling() + ")"; + } + t.addEnabling(enabling); + String minDelay = "", maxDelay = ""; + for (Transition tP : list) { + minDelay = minDelay + "min(" + tP.getDelay() + ","; + maxDelay = maxDelay + "max(" + tP.getDelay() + ","; + } + minDelay = minDelay + t.getDelay(); + maxDelay = maxDelay + t.getDelay(); + for (int i = 0; i < list.size(); i++) { + minDelay = minDelay + ")"; + maxDelay = maxDelay + ")"; + } + t.addDelay("uniform(" + minDelay + "," + maxDelay + ")"); + for (Transition tP : list) { + for (Place pP : tP.getPostset()) { + boolean contains = false; + for (Place p : t.getPostset()) { + if (p.equals(pP)) { + contains = true; + } + } + if (!contains) { + t.addPostset(pP); + } + } + removeTransition(tP.getLabel()); + } + } else { + for (Transition tP : list) { + if (!transitions.containsKey(tP.getLabel())) { + return; + } + } + String enabling = "(" + t.getEnabling() + ")"; + for (Transition tP : list) { + enabling = enabling + "|(" + tP.getEnabling() + ")"; + } + ExprTree dl = new ExprTree(this); + ExprTree du = new ExprTree(this); + ExprTree delay = new ExprTree(this); + ExprTree delay1 = t.getDelayTree(); + ExprTree e1 = t.getEnablingTree(); + ExprTree priority1 = new ExprTree(this); + if (t.containsPriority()) { + priority1 = t.getPriorityTree(); + } + ExprTree dl1, dl2, du1, du2; + if (delay1.isit == 'a' & delay1.op.equals("uniform")) { + dl1 = delay1.r1; + du1 = delay1.r2; + } else { + dl1 = new ExprTree(delay1); + du1 = new ExprTree(delay1); + } + e1.setNodeValues(e1, null, "INT", 'l'); + dl1.setNodeValues(e1, dl1, "*", 'a'); + du1.setNodeValues(e1, du1, "*", 'a'); + if (t.containsPriority()) { + priority1.setNodeValues(e1, priority1, "*", 'a'); + } + dl = dl1; + du = du1; + for (Transition tP : list) { + ExprTree delay2 = tP.getDelayTree(); + if (delay2.isit == 'a' & delay2.op.equals("uniform")) { + dl2 = delay2.r1; + du2 = delay2.r2; + } else { + dl2 = new ExprTree(delay2); + du2 = new ExprTree(delay2); + } + ExprTree e2 = tP.getEnablingTree(); + e2.setNodeValues(e2, null, "INT", 'l'); + dl2.setNodeValues(e2, dl2, "*", 'a'); + dl.setNodeValues(dl, dl2, "+", 'a'); + du2.setNodeValues(e2, du2, "*", 'a'); + du.setNodeValues(du, du2, "+", 'a'); + if (tP.containsPriority() && priority1 != null) { + ExprTree priority2 = tP.getPriorityTree(); + priority2.setNodeValues(e2, priority2, "*", 'a'); + priority1.setNodeValues(priority1, priority2, "+", 'a'); + } else if (tP.containsPriority()) { + ExprTree priority2 = tP.getPriorityTree(); + priority1.setNodeValues(e2, priority2, "*", 'a'); + } + } + if (!dl.isEqual(du)) { + delay.setNodeValues(dl, du, "uniform", 'a'); + } else { + delay = dl; + } + t.addEnabling(enabling); + t.addDelay(delay.toString()); + if (priority1 != null) { + t.addPriority(priority1.toString()); + } + } + for (Transition tP : list) { + removeTransition(tP.getLabel()); + } + } + + private static boolean hasAssignments(Transition trans) { + if (trans.getEnabling() != null) { + return true; + } + if (trans.getAssignments().size() > 0) { + return true; + } + return false; + } + + private boolean isGloballyDisabled(Transition trans) { + ExprTree enabling = trans.getEnablingTree(); + if (enabling == null) { + return false; + } + for (Transition t : transitions.values()) { + if (process_trans.get(t)!=null && process_trans.get(t).equals(process_trans.get(trans))) { + continue; + } + if (enabling.becomesTrue(t.getAssignments())) { + return false; + } + } + return true; + } + + private void addInterestingVariable(String var) { + if (!newestIntVars.contains(var)) { + newestIntVars.add(var); + if (continuous.containsKey(var)) { + newestIntVars.add(var + "_rate"); + } + } + } + + private static final String RANGE = "uniform\\((\\w+?),(\\w+?)\\)"; + +} \ No newline at end of file diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ExprTree.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ExprTree.java new file mode 100644 index 000000000..b1f292c26 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ExprTree.java @@ -0,0 +1,5678 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Set; + +import edu.utah.ece.async.ibiosim.dataModels.util.GlobalConstants; +import edu.utah.ece.async.lema.verification.timed_state_exploration.octagon.Equivalence; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.IntervalPair; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.LPNContAndRate; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.LPNContinuousPair; + +import java.lang.Math; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ExprTree { + + String op; + + char isit; // b=Boolean, i=Integer, c=Continuous, n=Number, t=Truth value, + // w=bitWise, a=Arithmetic, r=Relational, l=Logical + double lvalue, uvalue; + + String variable; + + double real; + + boolean logical; + + ExprTree r1, r2; + + private String tokvalue = ""; + + private int position = 0; + + public int token = 0; + + ExprTree newresult; + + private ArrayList booleanSignals, integerSignals, continuousSignals; + + private LPN lhpn; + + public String expression; + + public ExprTree() { + + } + /** + * This constructor is used in PlatuGrammar.g to convert LPNs from USF to LhpnFile. + * All LPNs from USF use integer variables only. So only integer signals are dealt with here. + * @param expression + */ + public ExprTree(String expression) { + this.expression = expression; + booleanSignals = new ArrayList(); + integerSignals = new ArrayList(); + continuousSignals = new ArrayList(); +// intexpr_gettok(expression); +// intexpr_L(expression); + } + + public ExprTree(LPN lhpn) { + this.lhpn = lhpn; + String[] bools = lhpn.getBooleanVars(); + String[] conts = lhpn.getContVars(); + String[] ints = lhpn.getIntVars(); + booleanSignals = new ArrayList(); + integerSignals = new ArrayList(); + continuousSignals = new ArrayList(); + for (int j = 0; j < bools.length; j++) { + booleanSignals.add(bools[j]); + } + for (int j = 0; j < conts.length; j++) { + continuousSignals.add(conts[j]); + } + for (int j = 0; j < ints.length; j++) { + integerSignals.add(ints[j]); + } + } + + public ExprTree(Abstraction abstraction) { + this.lhpn = abstraction; + String[] bools = abstraction.getBooleanVars(); + String[] conts = abstraction.getContVars(); + String[] ints = abstraction.getIntVars(); + booleanSignals = new ArrayList(); + integerSignals = new ArrayList(); + continuousSignals = new ArrayList(); + for (int j = 0; j < bools.length; j++) { + booleanSignals.add(bools[j]); + } + for (int j = 0; j < conts.length; j++) { + continuousSignals.add(conts[j]); + } + for (int j = 0; j < ints.length; j++) { + integerSignals.add(ints[j]); + } + } + +// public ExprTree(Transition transition) { +// } + + ExprTree(char willbe, int lNV, int uNV, String var) { + op = ""; + r1 = null; + r2 = null; + isit = willbe; + if ((isit == 'b') || (isit == 't')) + logical = true; + else + logical = false; + uvalue = uNV; + lvalue = lNV; + variable = var; + real = 0; + } + + public ExprTree(ExprTree nr1, ExprTree nr2, String nop, char willbe) { + op = nop; + r1 = nr1; + r2 = nr2; + isit = willbe; + if ((isit == 'r') || (isit == 'l')) { + logical = true; + uvalue = 1; + lvalue = 0; + } else { + logical = false; + uvalue = INFIN; + lvalue = -INFIN; + } + variable = null; + } + + public ExprTree(ExprTree source) { + if (source.op != null) { + op = source.op; + } + isit = source.isit; + lvalue = source.lvalue; + uvalue = source.uvalue; + if (source.variable != null) { + variable = source.variable; + } + real = source.real; + logical = source.logical; + if (source.r1 != null) { + r1 = source.r1; + } + if (source.r2 != null) { + r2 = source.r2; + } + if (source.tokvalue != null) { + tokvalue = source.tokvalue; + } + position = source.position; + token = source.token; + if (source.newresult != null) { + newresult = source.newresult; + } + if (source.booleanSignals != null) { + booleanSignals = source.booleanSignals; + } + if (source.integerSignals != null) { + integerSignals = source.integerSignals; + } + if (source.continuousSignals != null) { + continuousSignals = source.continuousSignals; + } + if (source.lhpn != null) { + lhpn = source.lhpn; + } + } + + /** + * This constructor takes a list of variables names. + * Each variable name is either an actual LPN discrete integer variable name, or + * a variable that is created during the Markovian analysis of nested properties. + * @param varNameList + */ + public ExprTree(ArrayList varNameList) { + booleanSignals = new ArrayList(); + continuousSignals = new ArrayList(); + integerSignals = new ArrayList(); + for (int j = 0; j < varNameList.size(); j++) { + integerSignals.add(varNameList.get(j)); + } + } + + public int intexpr_gettok(String expr) { + char c; + boolean readword; + boolean readnum; + boolean readsci; + boolean readsign; + + readword = false; + readnum = false; + readsci = false; + readsign = false; + tokvalue = ""; + while (position < expr.length()) { + c = expr.charAt(position); + position++; + switch (c) { + case '(': + case ')': + case '[': + case ']': + case ',': + case '~': + case '|': + case '&': + case '*': + case '^': + case '/': + case '%': + case '=': + case '<': + case '>': + if ((!readword) && (!readnum) && (!readsci)) { + return (c); + } + position--; + return (WORD); + case '+': + case '-': + if ((readsci) && (!readnum) && (readsign)) { + tokvalue += c; + readsign = false; + break; + } + if ((readsci) && (!readnum) && (!readsign)) { + return -1; + } else if ((!readword) && (!readnum) && (!readsci)) { + return (c); + } else { + position--; + return (WORD); + } + case ' ': + if (readword) { + return (WORD); + } + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (!readword) { + readnum = true; + } + tokvalue += c; + break; + case '.': + if (readsci) { + return -1; + } else if (!readword) { + readnum = true; + } + tokvalue += c; + break; + case 'E': + case 'e': + if (readsci) { + return -1; + } else if (readnum) { + readsci = true; + readnum = false; + readsign = true; + tokvalue += c; + break; + } /*else if (!readword){ // TODO: had to remove to make exponential parse but does scientific notation still work? + return -1; + }*/ + default: + if ((readnum) || (readsci)) { + return -1; + } + readword = true; + tokvalue += c; + break; + } + } + if ((!readword) && (!readnum)) { + return (END_OF_STRING); + } else if (readword || readnum) { + return (WORD); + } + return -1; + } + + public void intexpr_U(String expr) { + double temp; + + switch (token) { + case WORD: + if (tokvalue.toLowerCase().equals("and")) { + token = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + token = intexpr_gettok(expr); + intexpr_R(expr); + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + position = newresult.position; + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) + && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = ((int) (this).lvalue) + & ((int) newresult.lvalue); + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "&", 'w'); + } + (token) = intexpr_gettok(expr); + } else if (tokvalue.toLowerCase().equals("or")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ',') { + throw new IllegalArgumentException("ERROR: Expected a ,\n"); + } + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + position = newresult.position; + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) + && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = (int) (this).lvalue + | (int) newresult.lvalue; + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "|", 'w'); + } + (token) = intexpr_gettok(expr); + } else if (tokvalue.toLowerCase().equals("xor")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ',') { + throw new IllegalArgumentException("ERROR: Expected a ,\n"); + } + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + position = newresult.position; + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) + && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = (int) (this).lvalue + ^ (int) newresult.lvalue; + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "X", 'w'); + } + (token) = intexpr_gettok(expr); + } else if (tokvalue.toLowerCase().equals("min")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ',') { + throw new IllegalArgumentException("ERROR: Expected a ,\n"); + } + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + position = newresult.position; + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) + && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = Math.min((this).lvalue, newresult.lvalue); + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "m", 'a'); + } + (token) = intexpr_gettok(expr); + } else if (tokvalue.toLowerCase().equals("max")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ',') { + throw new IllegalArgumentException("ERROR: Expected a ,\n"); + } + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + position = newresult.position; + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) + && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = Math.max((this).lvalue, newresult.lvalue); + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "M", 'a'); + } + (token) = intexpr_gettok(expr); + } else if (tokvalue.toLowerCase().equals("idiv")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ',') { + throw new IllegalArgumentException("ERROR: Expected a ,\n"); + } + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + position = newresult.position; + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) + && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = Math + .floor((this).lvalue / newresult.lvalue); + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "i", 'a'); + } + (token) = intexpr_gettok(expr); + } else if (tokvalue.toLowerCase().equals("bit")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ',') { + throw new IllegalArgumentException("ERROR: Expected a ,\n"); + } + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + position = newresult.position; + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) + && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 't'; + (this).lvalue = ((int) (this).lvalue >> (int) newresult.lvalue) & 1; + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "[]", 'l'); + } + (token) = intexpr_gettok(expr); + } else if (tokvalue.toLowerCase().equals("floor")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + // simplify if operands are static + if (((this).isit == 'n') || ((this).isit == 't') + && ((this).lvalue == (this).uvalue) + && ((this).lvalue != INFIN) + && ((this).lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = Math.floor((this).lvalue); + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), null, "f", 'a'); + } + (token) = intexpr_gettok(expr); + } else if (tokvalue.toLowerCase().equals("ceil")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + // simplify if operands are static + if (((this).isit == 'n') || ((this).isit == 't') + && ((this).lvalue == (this).uvalue) + && ((this).lvalue != INFIN) + && ((this).lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = Math.ceil((this).lvalue); + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), null, "c", 'a'); + } + (token) = intexpr_gettok(expr); + } else if (tokvalue.toLowerCase().equals("not")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + // simplify if operands are static + if (((this).isit == 'n') || ((this).isit == 't') + && ((this).lvalue == (this).uvalue) + && ((this).lvalue != INFIN) + && ((this).lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = ~(int) (this).lvalue; + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), null, "~", 'w'); + } + (token) = intexpr_gettok(expr); + } else if (tokvalue.toLowerCase().equals("int")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_L(expr); + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + // simplify if operands are static + if (((this).isit == 'n') || ((this).isit == 't')) { + // DO NOTHING + } else { + setNodeValues((this), null, "INT", 'l'); + } + (token) = intexpr_gettok(expr); + } else if (tokvalue.equals("uniform")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ',') { + throw new IllegalArgumentException("ERROR: Expected a ,\n"); + } + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + position = newresult.position; + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + setNodeValues((this), newresult, "uniform", 'a'); + (token) = intexpr_gettok(expr); + } else if (tokvalue.equals("normal")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ',') { + throw new IllegalArgumentException("ERROR: Expected a ,\n"); + } + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + position = newresult.position; + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + setNodeValues((this), newresult, "normal", 'a'); + (token) = intexpr_gettok(expr); + } else if (tokvalue.equals("gamma")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ',') { + throw new IllegalArgumentException("ERROR: Expected a ,\n"); + } + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + position = newresult.position; + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + setNodeValues((this), newresult, "gamma", 'a'); + (token) = intexpr_gettok(expr); + } else if (tokvalue.equals("lognormal")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ',') { + throw new IllegalArgumentException("ERROR: Expected a ,\n"); + } + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + position = newresult.position; + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + setNodeValues((this), newresult, "lognormal", 'a'); + (token) = intexpr_gettok(expr); + } else if (tokvalue.equals("binomial")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ',') { + throw new IllegalArgumentException("ERROR: Expected a ,\n"); + } + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + position = newresult.position; + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + setNodeValues((this), newresult, "binomial", 'a'); + (token) = intexpr_gettok(expr); + } else if (tokvalue.equals("exponential")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + setNodeValues((this), null, "exponential", 'a'); + (token) = intexpr_gettok(expr); + } else if (tokvalue.equals("chisq")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + setNodeValues((this), null, "chisq", 'a'); + (token) = intexpr_gettok(expr); + } else if (tokvalue.equals("laplace")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + setNodeValues((this), null, "laplace", 'a'); + (token) = intexpr_gettok(expr); + } else if (tokvalue.equals("cauchy")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + setNodeValues((this), null, "cauchy", 'a'); + (token) = intexpr_gettok(expr); + } else if (tokvalue.equals("rayleigh")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + setNodeValues((this), null, "rayleigh", 'a'); + (token) = intexpr_gettok(expr); + } else if (tokvalue.equals("poisson")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + setNodeValues((this), null, "poisson", 'a'); + (token) = intexpr_gettok(expr); + } else if (tokvalue.equals("bernoulli")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + setNodeValues((this), null, "bernoulli", 'a'); + (token) = intexpr_gettok(expr); + } else if (tokvalue.equals("rate")) { + (token) = intexpr_gettok(expr); + if ((token) != '(') { + throw new IllegalArgumentException("ERROR: Expected a (\n"); + } + (token) = intexpr_gettok(expr); + intexpr_R(expr); + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + setNodeValues((this), null, "rate", 'a'); + (token) = intexpr_gettok(expr); + } else if ((tokvalue.equals("true")) || tokvalue.equals("TRUE")) { + setVarValues('t', 1, 1, null); + (token) = intexpr_gettok(expr); + } else if ((tokvalue.equals("maybe")) || tokvalue.equals("MAYBE")) { + setVarValues('t', 0, 1, null); + (token) = intexpr_gettok(expr); + } + else if (tokvalue.equals("t") && !booleanSignals.contains(tokvalue) && !integerSignals.contains(tokvalue) + && !continuousSignals.contains(tokvalue)) { + setVarValues('t', 1, 1, null); + (token) = intexpr_gettok(expr); + } + else if (tokvalue.equals("T") && !booleanSignals.contains(tokvalue) && !integerSignals.contains(tokvalue) + && !continuousSignals.contains(tokvalue)) { + setVarValues('t', 1, 1, null); + (token) = intexpr_gettok(expr); + } + else if ((tokvalue.equals("false")) || tokvalue.equals("FALSE")) { + setVarValues('t', 0, 0, null); + (token) = intexpr_gettok(expr); + } + else if (tokvalue.equals("f") && !booleanSignals.contains(tokvalue) && !integerSignals.contains(tokvalue) + && !continuousSignals.contains(tokvalue)) { + setVarValues('t', 0, 0, null); + (token) = intexpr_gettok(expr); + } + else if (tokvalue.equals("F") && !booleanSignals.contains(tokvalue) && !integerSignals.contains(tokvalue) + && !continuousSignals.contains(tokvalue)) { + setVarValues('t', 0, 0, null); + (token) = intexpr_gettok(expr); + } else if ((tokvalue.toLowerCase().equals("unknown"))) { + setVarValues('t', 0, 1, null); + (token) = intexpr_gettok(expr); + } else if (tokvalue.toLowerCase().equals("inf")) { + setVarValues('n', INFIN, INFIN, null); + token = intexpr_gettok(expr); + } else { + // do boolean lookup here!!! + if (booleanSignals.contains(tokvalue)) { + setVarValues('b', 0, 1, tokvalue); + (token) = intexpr_gettok(expr); + return; + } + else if (integerSignals.contains(tokvalue)) { + setVarValues('i', -INFIN, INFIN, tokvalue); + (token) = intexpr_gettok(expr); + return; + } + else if (continuousSignals.contains(tokvalue)) { + setVarValues('c', -INFIN, INFIN, tokvalue); + (token) = intexpr_gettok(expr); + return; + } + if (tokvalue.equals("")) { + throw new IllegalArgumentException(String.format( + "U1:ERROR(%s): Expected a ID, Number, or a (\n", + tokvalue)); + } else if ((tokvalue.charAt(0)) > ('9') + || ((tokvalue.charAt(0)) < '0')) { + throw new IllegalArgumentException(String.format( + "U1:ERROR(%s): Expected a ID, Number, or a (\n", + tokvalue)); + } + temp = Double.parseDouble(tokvalue); + setVarValues('n', temp, temp, null); + token = intexpr_gettok(expr); + } + break; + case '(': + (token) = intexpr_gettok(expr); + intexpr_L(expr); + if ((token) != ')') { + throw new IllegalArgumentException("ERROR: Expected a )\n"); + } + (token) = intexpr_gettok(expr); + break; + default: + throw new IllegalArgumentException("U2:ERROR: Expected a ID, Number, or a (\n"); + } + } + + public void intexpr_T(String expr) { + switch (token) { + case WORD: + case '(': + intexpr_U(expr); + break; + case '-': + (token) = intexpr_gettok(expr); + intexpr_U(expr); + // simplify if operands are static + if ((((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && ((this).lvalue != INFIN) && ((this).lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = -((this).lvalue); + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), null, "U-", 'a'); + } + break; + default: + throw new IllegalArgumentException("T:ERROR: Expected a ID, Number, (, or -\n"); + } + } + + public void intexpr_C(String expr) { + newresult = new ExprTree(this); + switch (token) { + case '*': + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_T(expr); + token = newresult.token; + position = newresult.position; + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = (this).lvalue * newresult.lvalue; + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "*", 'a'); + } + intexpr_C(expr); + break; + case '^': + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_T(expr); + token = newresult.token; + position = newresult.position; + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = Math.pow(lvalue, newresult.lvalue); + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "^", 'a'); + } + intexpr_C(expr); + break; + case '/': + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_T(expr); + token = newresult.token; + position = newresult.position; + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = (this).lvalue / newresult.lvalue; + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "/", 'a'); + } + intexpr_C(expr); + break; + case '%': + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_T(expr); + token = newresult.token; + position = newresult.position; + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = (this).lvalue % newresult.lvalue; + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "%", 'a'); + } + intexpr_C(expr); + break; + case '+': + case '-': + case ')': + case '[': + case ']': + case '|': + case '&': + case '=': + case '<': + case '>': + case ',': + case IMPLIES: + case END_OF_STRING: + break; + case '(': + case WORD: + newresult.intexpr_T(expr); + token = newresult.token; + position = newresult.position; + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = (this).lvalue * newresult.lvalue; + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "*", 'a'); + } + intexpr_C(expr); + break; + + default: + throw new IllegalArgumentException("ERROR: Expected a * or /\n"); + } + } + + public void intexpr_B(String expr) { + newresult = new ExprTree(this); + switch (token) { + case '+': + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_S(expr); + token = newresult.token; + position = newresult.position; + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = (this).lvalue + newresult.lvalue; + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "+", 'a'); + } + intexpr_B(expr); + break; + case '-': + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_S(expr); + token = newresult.token; + position = newresult.position; + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 'n'; + (this).lvalue = (this).lvalue - newresult.lvalue; + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "-", 'a'); + } + intexpr_B(expr); + break; + case ')': + case '[': + case ']': + case '|': + case '&': + case '=': + case '<': + case '>': + case ',': + case IMPLIES: + case END_OF_STRING: + break; + default: + throw new IllegalArgumentException("ERROR: Expected a + or -\n"); + } + } + + public void intexpr_S(String expr) { + switch (token) { + case WORD: + case '(': + case '-': + intexpr_T(expr); + intexpr_C(expr); + break; + default: + throw new IllegalArgumentException("S:ERROR: Expected a ID, Number, (, or -\n"); + } + } + + public void intexpr_R(String expr) { + switch (token) { + case WORD: + case '(': + case '-': + intexpr_S(expr); + intexpr_B(expr); + break; + default: + throw new IllegalArgumentException("R:ERROR: Expected a ID, Number, (, or -\n"); + } + } + + public void intexpr_P(String expr) { + newresult = new ExprTree(this); + //int spos, i; + String ineq = ""; + String comp; + switch (token) { + case '=': + //spos = position; + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + tokvalue = newresult.tokvalue; + position = newresult.position; + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 't'; + if (this.lvalue == newresult.lvalue) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + } else { + if ((this).isit == 'c') { + comp = variable; +// comp += "="; +//// int paren = 0; +//// for (i = spos; i < position; i++) { +//// if (expr.charAt(i) == '(') +//// paren++; +//// if (expr.charAt(i) == ')') +//// paren--; +//// ineq = ineq + expr.charAt(i); +//// } +// comp += ineq; + if (booleanSignals.contains(comp)) { + this.isit = 'b'; + this.variable = comp; + this.lvalue = 0; + this.uvalue = 1; + return; + } + booleanSignals.add(comp); + this.isit = 'b'; + this.variable = comp; + this.lvalue = 0; + this.uvalue = 1; + return; + } + setNodeValues((this), newresult, "==", 'r'); + } + break; + case '>': + //spos = position; + (token) = intexpr_gettok(expr); + newresult.token = token; + if ((token) == '=') { + //spos = position; + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + tokvalue = newresult.tokvalue; + position = newresult.position; + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) + && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 't'; + if ((this).lvalue >= newresult.lvalue) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, ">=", 'r'); + } + } else { + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + tokvalue = newresult.tokvalue; + position = newresult.position; + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) + && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 't'; + if ((this).lvalue > newresult.lvalue) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, ">", 'r'); + } + } + break; + case '<': + //spos = position; + (token) = intexpr_gettok(expr); + if ((token) == '=') { + //spos = position; + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + tokvalue = newresult.tokvalue; + position = newresult.position; + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) + && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 't'; + if ((this).lvalue <= newresult.lvalue) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "<=", 'r'); + } + } else { + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + tokvalue = newresult.tokvalue; + position = newresult.position; + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) + && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 't'; + if ((this).lvalue < newresult.lvalue) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "<", 'r'); + } + } + break; + case '[': + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_R(expr); + token = newresult.token; + tokvalue = newresult.tokvalue; + position = newresult.position; + if ((token) != ']') { + throw new IllegalArgumentException("ERROR: Expected a ]\n"); + } + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 't'; + (this).lvalue = (((int) (this).lvalue) >> ((int) newresult.lvalue)) & 1; + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "[]", 'l'); + } + (token) = intexpr_gettok(expr); + break; + case '&': + case '|': + case ')': + case IMPLIES: + case END_OF_STRING: + break; + default: + throw new IllegalArgumentException("ERROR: Expected a [, =, <, or >\n"); + } + } + + public void intexpr_O(String expr) { + switch (token) { + case WORD: + case '(': + case '-': + intexpr_R(expr); + intexpr_P(expr); + break; + default: + throw new IllegalArgumentException("O:ERROR: Expected a ID, Number, or a (\n"); + } + } + + public void intexpr_N(String expr) { + switch (token) { + case WORD: + case '-': + case '(': + intexpr_O(expr); + break; + case '~': + (token) = intexpr_gettok(expr); + intexpr_O(expr); + // simplify if operands are static + if ((((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && ((this).lvalue != INFIN) && ((this).lvalue != -INFIN)) { + (this).isit = 't'; + if (this.lvalue == 1) { + this.lvalue = 0; + } else { + this.lvalue = 1; + } + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), null, "!", 'l'); + } + break; + default: + throw new IllegalArgumentException("N:ERROR: Expected a ID, Number, (, or -\n"); + } + } + + public void intexpr_E(String expr) { + newresult = new ExprTree(this); + switch (token) { + case '&': + token = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_N(expr); + token = newresult.token; + position = newresult.position; + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 't'; + if ((this.lvalue == 0) || (newresult.lvalue == 0)) { + this.lvalue = 0; + } else { + this.lvalue = 1; + } + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "&&", 'l'); + } + intexpr_E(expr); + break; + case '|': + case ')': + case IMPLIES: + case END_OF_STRING: + break; + default: + throw new IllegalArgumentException(String.format("ERROR(%c): Expected an &\n", (token))); + } + } + + public void intexpr_D(String expr) { + newresult = new ExprTree(this); + switch (token) { + case '|': + (token) = intexpr_gettok(expr); + newresult.token = token; + newresult.tokvalue = tokvalue; + newresult.position = position; + newresult.intexpr_M(expr); + token = newresult.token; + position = newresult.position; + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 't'; + if (this.lvalue != 0 || newresult.lvalue != 0) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + } else { + setNodeValues((this), newresult, "||", 'l'); + } + intexpr_D(expr); + break; + case ')': + case END_OF_STRING: + break; + case IMPLIES: + (token) = intexpr_gettok(expr); + intexpr_M(expr); + // simplify if operands are static + if (((newresult.isit == 'n') || (newresult.isit == 't')) + && (((this).isit == 'n') || ((this).isit == 't')) + && ((this).lvalue == (this).uvalue) + && (newresult.lvalue == newresult.uvalue) + && ((this).lvalue != INFIN) && ((this).lvalue != -INFIN) + && (newresult.lvalue != INFIN) + && (newresult.lvalue != -INFIN)) { + (this).isit = 't'; + if (this.lvalue != 0 || newresult.lvalue == 0) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + } else { + setNodeValues(this, newresult, "->", 'l'); + } + intexpr_D(expr); + break; + default: + throw new IllegalArgumentException("ERROR: Expected an | or ->\n"); + } + } + + public void intexpr_M(String expr) { + switch (token) { + case WORD: + case '(': + case '~': + case '-': + intexpr_N(expr); + intexpr_E(expr); + break; + default: + throw new IllegalArgumentException("M: ERROR: Expected a ID, Number, (, or -\n"); + } + } + + public void intexpr_L(String expr) { + switch (token) { + case WORD: + case '(': + case '~': + case '-': + intexpr_M(expr); + intexpr_D(expr); + break; + default: + throw new IllegalArgumentException("L:ERROR: Expected a ID, Number, (, or -\n"); + } + } + + @Override + public String toString() { + String result = ""; + result = getElement("LHPN"); + return result; + } + + public String toString(String type) { + String result = ""; + result = getElement(type); + return result; + } + + public String toString(String type, String lhpnSbml) { + String result = ""; + result = getElement(lhpnSbml); + if (type.equals("continuous") || type.equals("integer")) { + if (isit == 't') { + if (uvalue == 0) { + result = "0"; + } else { + result = "1"; + } + } + } else { + if (isit == 'n') { + if (uvalue == 0) { + result = "FALSE"; + } else { + result = "TRUE"; + } + } + } + return result; + } + + public boolean implies(ExprTree expr) { + if (isEqual(expr)) { + return true; + } + if (expr.isit == 'l' && expr.op.equals("||")) { + if (implies(expr.r1) || implies(expr.r2)) { + return true; + } + } else if (expr.isit == 'l' && expr.op.equals("&&")) { + if (implies(expr.r1) && implies(expr.r2)) { + return true; + } + } + switch (isit) { + case 't': // Truth value + if (uvalue == 1 && lvalue == 1) { + return false; + } else if (uvalue == 0 && lvalue == 0) { + return true; + } else { + return false; + } + case 'r': // Relational + if (op.contains(">")) { + if (expr.isit == 'r' && expr.op.contains(">")) { + if (r2.lvalue > expr.r2.uvalue) { + return true; + } else if (r2.lvalue == expr.r2.uvalue + && op.length() >= expr.op.length()) { + return true; + } + } + } else if (op.contains("<")) { + if (expr.isit == 'r' && expr.op.contains("<")) { + if (r2.lvalue < expr.r2.uvalue) { + return true; + } else if (r2.lvalue == expr.r2.uvalue + && op.length() >= expr.op.length()) { + return true; + } + } + } + return false; + case 'l': // Logical + if (op.equals("&&")) { + if (expr.isit == 'b') { + if (r1.implies(expr) || r2.implies(expr)) { + return true; + } + } + } else if (op.equals("||")) { + if (expr.isit == 'b') { + if (r1.implies(expr) && r2.implies(expr)) { + return true; + } + } + } + return false; + case 'b': // Boolean + case 'i': // Integer + case 'c': // Continuous + case 'n': // Number + case 'w': // bitWise + case 'a': // Arithmetic + default: + return false; + } + } + + public boolean containsVar(String var) { + switch (isit) { + case 'b': // Boolean + case 'i': // Integer + case 'c': // Continuous + if (variable.equals(var)) + return true; + return false; + case 'r': // Relational + case 'l': // Logical + case 'a': // Arithmetic + case 'w': // bitWise + if (r1 != null) { + if (r1.containsVar(var)) { + return true; + } + } + if (r2 != null) { + if (r2.containsVar(var)) { + return true; + } + } + return false; + case 'n': // Number + case 't': // Truth value + default: + return false; + } + } + + public ArrayList getVars() { + ArrayList vars = new ArrayList(); + switch (isit) { + case 'b': // Boolean + case 'i': // Integer + case 'c': // Continuous + if (!vars.contains(variable)) + vars.add(variable); + break; + case 'r': // Relational + case 'l': // Logical + case 'a': // Arithmetic + case 'w': // bitWise + if (r1 != null) + vars.addAll(r1.getVars()); + if (r2 != null) + vars.addAll(r2.getVars()); + break; + case 'n': // Number + case 't': // Truth value + default: + break; + } + return vars; + } + + /** + * Returns a list of the continuous variable's names that are + * contained in this ExprTree. + * @return + * The list of name of the continuous variables in this + * ExprTree. + */ + public ArrayList getContVars() { + ArrayList vars = new ArrayList(); + switch (isit) { + //case 'b': // Boolean + //case 'i': // Integer + case 'c': // Continuous + if (!vars.contains(variable)) + vars.add(variable); + break; + case 'r': // Relational + case 'l': // Logical + case 'a': // Arithmetic + case 'w': // bitWise + if (r1 != null) + vars.addAll(r1.getVars()); + if (r2 != null) + vars.addAll(r2.getVars()); + break; + case 'n': // Number + case 't': // Truth value + default: + break; + } + return vars; + } + + public void scaleVals(Double scaleFactor) { // SB + switch (isit) { + case 'b': // Boolean + case 'i': // Integer + case 'c': // Continuous + break; + case 'r': // Relational + case 'l': // Logical + case 'a': // Arithmetic + case 'w': // bitWise + if (r1 != null) + r1.scaleVals(scaleFactor); + if (r2 != null) + r2.scaleVals(scaleFactor); + break; + case 'n': // Number + variable = String + .valueOf((int) (Double.parseDouble(variable) * scaleFactor)); + break; + case 't': // Truth value + default: + break; + } + } + + public boolean containsCont() { + switch (isit) { + case 'b': // Boolean + case 't': // Truth value + return false; + case 'i': // Integer + case 'c': // Continuous + case 'r': // Relational + case 'a': // Arithmetic + case 'n': // Number + return true; + case 'l': // Logical + case 'w': // bitWise + boolean r1cont = false, + r2cont = false; + if (r1 != null) + r1cont = r1.containsCont(); + if (r2 != null) + r2cont = r2.containsCont(); + return (r1cont || r2cont); + } + return false; + } + + /** + * This method will return true if the + * expression tree contains a continuous variable. + * This is difference from containsCont() which + * will return true if there is an integer, + * relational, arithmetic or number. + * @return + * True if this ExprTree continuous a + * continuous variable. + */ + public boolean containsExactlyCont() { + switch (isit) { + // These are leaf nodes that we are not looking for. + case 'b': // Boolean + case 't': // Truth value + case 'i': // Integer + case 'n': // Number + return false; + // This is what we are looking for. + case 'c': // Continuous + return true; + // The subexpression may contain a continuous variable + // so need to check further. + case 'a': // Arithmetic + case 'r': // Relational + case 'l': // Logical + case 'w': // bitWise + boolean r1cont = false, + r2cont = false; + if (r1 != null) + r1cont = r1.containsExactlyCont(); + if (r2 != null) + r2cont = r2.containsExactlyCont(); + return (r1cont || r2cont); + } + return false; + } + + public void replace(String var, String type, ExprTree e) { + if (this == e) { + return; + } + boolean simplify = false; + switch (isit) { + case 'b': // Boolean + case 'i': // Integer + case 'c': // Continuous + if (variable.equals(var)) { + if (e.isit == 'a' || e.isit == 'r' || e.isit == 'l' + || e.isit == 'w') { + setNodeValues(e.r1, e.r2, e.op, e.isit); + } else { + setVarValues(e.isit, e.lvalue, e.uvalue, e.variable); + } + } + return; + case 'w': // bitWise + case 'l': // Logical + case 'r': // Relational + case 'a': // Arithmetic + if (r1 != null || r2 != null) { + if (r1 != null) + r1.replace(var, type, e); + if (r2 != null) + r2.replace(var, type, e); + break; + } + // simplify if operands are static + if (op.equals("&&")) { + if ((r1.isit == 'n') || (r1.isit == 't')) { + if (r1.lvalue == 0) { + setVarValues('t', 0.0, 0.0, null); + simplify = true; + } else { + if (r2.isit == 'l' || r2.isit == 'a' || r2.isit == 'w' + || r2.isit == 'r') { + setNodeValues(r2.r1, r2.r2, r2.op, r2.isit); + } else { + setVarValues(r2.isit, r2.lvalue, r2.uvalue, + r2.variable); + } + } + } else if (((r2).isit == 'n') || ((r2).isit == 't')) { + if (r2.lvalue == 0) { + setVarValues('t', 0.0, 0.0, null); + simplify = true; + } else { + if (r1.isit == 'l' || r1.isit == 'a' || r1.isit == 'w' + || r1.isit == 'r') { + setNodeValues(r1.r1, r1.r2, r1.op, r1.isit); + } else { + setVarValues(r1.isit, r1.lvalue, r1.uvalue, + r1.variable); + } + } + } + } else if (op.equals("||")) { + if ((r1.isit == 'n') || (r1.isit == 't')) { + if (r1.lvalue == 1) { + setVarValues('t', 1.0, 1.0, null); + simplify = true; + } else { + if (r2.isit == 'l' || r2.isit == 'a' || r2.isit == 'w' + || r2.isit == 'r') { + setNodeValues(r2.r1, r2.r2, r2.op, r2.isit); + } else { + setVarValues(r2.isit, r2.lvalue, r2.uvalue, + r2.variable); + } + } + } else if (((r2).isit == 'n') || ((r2).isit == 't')) { + if (r2.lvalue == 1) { + setVarValues('t', 1.0, 1.0, null); + simplify = true; + } else { + if (r1.isit == 'l' || r1.isit == 'a' || r1.isit == 'w' + || r1.isit == 'r') { + setNodeValues(r1.r1, r1.r2, r1.op, r1.isit); + } else { + setVarValues(r1.isit, r1.lvalue, r1.uvalue, + r1.variable); + } + } + } else if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 't'; + if (r1.lvalue != 0 || r2.lvalue != 0) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("->")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 't'; + if (r1.lvalue != 0 || r2.lvalue == 0) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("!")) { + if (((r1).isit == 'n') || ((r1).isit == 't')) { + (this).isit = 't'; + if (r1.lvalue == 1) { + this.lvalue = 0; + } else { + this.lvalue = 1; + } + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("==")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 't'; + if (r1.lvalue == r2.lvalue) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals(">=")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 't'; + if ((r1).lvalue >= r2.lvalue) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals(">")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 't'; + if ((r1).lvalue > r2.lvalue) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("<=")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 't'; + if ((r1).lvalue <= r2.lvalue) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("<")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 't'; + if ((r1).lvalue < r2.lvalue) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("&")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = ((int) (r1).lvalue) & ((int) r2.lvalue); + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("|")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = (int) (r1).lvalue | (int) r2.lvalue; + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("X")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = (int) (r1).lvalue ^ (int) r2.lvalue; + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("m")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = Math.min((r1).lvalue, r2.lvalue); + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("M")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = Math.max((r1).lvalue, r2.lvalue); + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("i")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = Math.floor((r1).lvalue / (r2).lvalue); + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("f")) { + if (((r1).isit == 'n') || ((r1).isit == 't')) { + (this).isit = 'n'; + (this).lvalue = Math.floor((r1).lvalue); + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("c")) { + if (((r1).isit == 'n') || ((r1).isit == 't')) { + (this).isit = 'n'; + (this).lvalue = Math.ceil((r1).lvalue); + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("~")) { + if (((r1).isit == 'n') || ((r1).isit == 't')) { + (this).isit = 'n'; + (this).lvalue = ~(int) (r1).lvalue; + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("[]")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 't'; + (this).lvalue = (((int) (r1).lvalue) >> ((int) r2.lvalue)) & 1; + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("U-")) { + if (((r1).isit == 'n') || ((r1).isit == 't')) { + (this).isit = 'n'; + (this).lvalue = -((r1).lvalue); + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("*")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = (r1).lvalue * r2.lvalue; + (this).uvalue = (this).lvalue; + } + } else if (op.equals("/")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = (r1).lvalue / r2.lvalue; + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("%")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = (r1).lvalue % r2.lvalue; + (this).uvalue = (this).lvalue; + simplify = true; + } + } else if (op.equals("+")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = (r1).lvalue + r2.lvalue; + (this).uvalue = (this).lvalue; + } else if ((r1.isit == 'n') || (r1.isit == 't')) { + if (r1.lvalue == 0 && r1.uvalue == 0) { + setNodeValues(r2.r1, r2.r2, r2.op, r2.isit); + } + } else if (((r2).isit == 'n') || ((r2).isit == 't')) { + if (r2.lvalue == 0 && r2.uvalue == 0) { + setNodeValues(r1.r1, r1.r2, r1.op, r1.isit); + } + } + } else if (op.equals("-")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = (r1).lvalue - r2.lvalue; + (this).uvalue = (this).lvalue; + simplify = true; + } + } + break; + case 't': // Truth value + if (lvalue != 0 && uvalue != 0) { + lvalue = 1; + uvalue = 1; + } else if (lvalue != 0 || uvalue != 0) { + lvalue = 0; + uvalue = 1; + } + return; + case 'n': // Number + break; + } + if (simplify) { + if (type.equals("integer") || type.equals("continuous")) { + isit = 'n'; + } else { + isit = 't'; + if (lvalue != 0 && uvalue != 0) { + lvalue = 1; + uvalue = 1; + } else if (lvalue != 0 || uvalue != 0) { + lvalue = 0; + uvalue = 1; + } + } + } + } + + public void replaceVar(String var1, String var2) { + switch (isit) { + case 'b': // Boolean + case 'i': // Integer + case 'c': // Continuous + if (variable.equals(var1)) { + variable = var2; + } + return; + case 'w': // bitWise + case 'l': // Logical + case 'r': // Relational + case 'a': // Arithmetic + if (r1 != null) + r1.replaceVar(var1, var2); + if (r2 != null) + r2.replaceVar(var1, var2); + break; + case 't': // Truth value + case 'n': // Number + break; + } + } + + public char getChange(HashMap variables) { + switch (isit) { + case 'b': // Boolean + if (variables.containsKey(variable)) { + if (variables.get(variable).toString().toLowerCase().equals("false")) + return 'F'; + if (variables.get(variable).toString().toLowerCase().equals("true")) + return 'T'; + return 'X'; + } + return 'U'; + case 't': // Truth value + /* + if (uvalue == 0) + return 'F'; + else if (lvalue == 1) + return 'T'; + */ + return 'U'; + case 'l': // Logical + if (op.equals("||")) { + if (r1.getChange(variables) == 'T' + || r2.getChange(variables) == 'T') { + return 'T'; + } else if (r1.getChange(variables) == 'X' + || r2.getChange(variables) == 'X') { + return 'X'; + } else if (r1.getChange(variables) == 't') { + if (r2.getChange(variables) == 'f') { + return 'X'; + } + return 't'; + } else if (r2.getChange(variables) == 't') { + if (r1.getChange(variables) == 'f') { + return 'X'; + } + return 't'; + } else if (r1.getChange(variables) == 'f' + || r2.getChange(variables) == 'f') { + return 'f'; + } else if (r1.getChange(variables) == 'F') { + if (r2.getChange(variables) == 'F') { + return 'F'; + } + return 'f'; + } else if (r2.getChange(variables) == 'F') { + return 'f'; + } + return 'U'; + } else if (op.equals("&&")) { + if (r1.getChange(variables) == 'F' + || r2.getChange(variables) == 'F') { + return 'F'; + } else if (r1.getChange(variables) == 'X' + || r2.getChange(variables) == 'X') { + return 'X'; + } else if (r1.getChange(variables) == 'f') { + if (r2.getChange(variables) == 't') { + return 'X'; + } + return 'f'; + } else if (r2.getChange(variables) == 'f') { + if (r1.getChange(variables) == 't') { + return 'X'; + } + return 'f'; + } else if (r1.getChange(variables) == 't' + || r2.getChange(variables) == 't') { + return 't'; + } else if (r1.getChange(variables) == 'T') { + if (r2.getChange(variables) == 'T') { + return 'T'; + } + return 't'; + } else if (r2.getChange(variables) == 'T') { + return 't'; + } + return 'U'; + } else if (op.equals("!")) { + if (r1.getChange(variables) == 'T') { + return 'F'; + } else if (r1.getChange(variables) == 'F') { + return 'T'; + } else if (r1.getChange(variables) == 't') { + return 'f'; + } else if (r1.getChange(variables) == 'f') { + return 't'; + } + return r1.getChange(variables); + } else if (op.equals("->")) { + if (r1.getChange(variables) == 'T' + || r2.getChange(variables) == 'F') { + return 'T'; + } else if (r1.getChange(variables) == 'X' + || r2.getChange(variables) == 'X') { + return 'X'; + } else if (r1.getChange(variables) == 't') { + if (r2.getChange(variables) == 't') { + return 'X'; + } + return 't'; + } else if (r2.getChange(variables) == 'f') { + if (r1.getChange(variables) == 'f') { + return 'X'; + } + return 't'; + } else if (r1.getChange(variables) == 'f') { + return 'f'; + } else if (r2.getChange(variables) == 't') { + return 'f'; + } else if (r1.getChange(variables) == 'F') { + if (r2.getChange(variables) == 'T') { + return 'F'; + } + return 'f'; + } else if (r2.getChange(variables) == 'T') { + return 'f'; + } + return 'U'; + } + break; + case 'r': // Relational + boolean flag = false; + for (String var : getVars()) { + if (variables.containsKey(var)) { + flag = true; + break; + } + } + if (!flag) { + return 'U'; + } + if (op.equals("==")) { + if (r1.evaluateExpr(variables) == r2.evaluateExpr(variables)) { + return 'T'; + } else if (new Double(r1.evaluateExpr(variables)) + .equals(Double.NaN) + || new Double(r2.evaluateExpr(variables)) + .equals(Double.NaN)) { + return 'X'; + } + return 'F'; + } else if (op.equals(">=")) { + if (r1.evaluateExpr(variables) >= r2.evaluateExpr(variables)) { + return 'T'; + } else if (new Double(r2.evaluateExpr(variables)) + .equals(Double.NaN) + || new Double(r1.evaluateExpr(variables)) + .equals(Double.NaN)) { + return 'X'; + } + return 'F'; + } else if (op.equals("<=")) { + if (r1.evaluateExpr(variables) <= r2.evaluateExpr(variables)) { + return 'T'; + } else if (new Double(r1.evaluateExpr(variables)) + .equals(Double.NaN) + || new Double(r2.evaluateExpr(variables)) + .equals(Double.NaN)) { + return 'X'; + } + return 'F'; + } else if (op.equals(">")) { + if (r1.evaluateExpr(variables) > r2.evaluateExpr(variables)) { + return 'T'; + } else if (new Double(r1.evaluateExpr(variables)) + .equals(Double.NaN) + || new Double(r2.evaluateExpr(variables)) + .equals(Double.NaN)) { + return 'X'; + } + return 'F'; + } else if (op.equals("<")) { + if (r1.evaluateExpr(variables) < r2.evaluateExpr(variables)) { + return 'T'; + } else if (new Double(r1.evaluateExpr(variables)) + .equals(Double.NaN) + || new Double(r2.evaluateExpr(variables)) + .equals(Double.NaN)) { + return 'X'; + } + return 'F'; + } + return 'X'; + case 'i': // Integer + if (variables.containsKey(variable)) { + try { + if (Integer.parseInt(variables.get(variable)) == 0.0) { + return 'F'; + } + return 'T'; + } catch (Exception e) { + return 'X'; + } + } + return 'U'; + case 'c': // Continuous + return 'X'; + case 'n': // Number + if (uvalue == 0.0 && lvalue == 0.0) { + return 'F'; + } + return 'T'; + } + return 'X'; + } + + public boolean becomesFalse(HashMap variables) { + switch (isit) { + case 'b': // Boolean + if (variables.containsKey(variable)) + if (variables.get(variable).toString().toLowerCase().equals( + "false")) + return true; + return false; + case 't': // Truth value + if (lvalue == 0) + return true; + return false; + case 'l': // Logical + if (op.equals("||")) { + if (r1.becomesFalse(variables) && r2.becomesFalse(variables)) { + return true; + } + return false; + } else if (op.equals("&&")) { + if ((r1.becomesFalse(variables) && !r2.becomesTrue(variables)) + || (!r1.becomesTrue(variables) && r2 + .becomesFalse(variables))) + return true; + return false; + } else if (op.equals("==")) { + if (!(r1.isEqual(r2) || r1.evaluateExpr(variables) == r2 + .evaluateExpr(variables))) + return true; + return false; + } else if (op.equals("!")) { + if (r1.becomesTrue(variables)) + return true; + return false; + } else if (op.equals("->")) { + if (r1.becomesFalse(variables) || r2.becomesTrue(variables)) { + return true; + } + return false; + } else if (op.equals("[]")) { + if (!(evaluateExpr(variables) == 0.0)) { + return true; + } + return false; + } + break; + case 'w': // bitWise + if (op.equals("&")) { + if (!(evaluateExpr(variables) == 0.0)) { + return true; + } + return false; + } else if (op.equals("|")) { + if (!(evaluateExpr(variables) == 0.0)) { + return true; + } + return false; + } else if (op.equals("X")) { + if (!(evaluateExpr(variables) == 0.0)) { + return true; + } + return false; + } else if (op.equals("~")) { + if (!(evaluateExpr(variables) == 0.0)) { + return true; + } + return false; + } + break; + case 'r': // Relational + if (r1.isit == 'i') { + if (!variables.containsKey(r1.variable)) { + return false; + } + if (op.equals("==")) { + if (r1.evaluateExpr(variables) == r2 + .evaluateExpr(variables)) { + return false; + } + return true; + } else if (op.equals(">=")) { + if (r1.evaluateExpr(variables) >= r2 + .evaluateExpr(variables)) { + return false; + } + return true; + } else if (op.equals("<=")) { + if (r1.evaluateExpr(variables) <= r2 + .evaluateExpr(variables)) { + return false; + } + return true; + } else if (op.equals(">")) { + if (r1.evaluateExpr(variables) > r2.evaluateExpr(variables)) { + return false; + } + return true; + } else if (op.equals("<")) { + if (r1.evaluateExpr(variables) < r2.evaluateExpr(variables)) { + return false; + } + return true; + } + return true; + } + return true; + case 'i': // Integer + if (variables.containsKey(variable)) { + if (Integer.parseInt(variables.get(variable)) == 0.0) { + return true; + } + return false; + } + return false; + case 'c': // Continuous + return true; + case 'a': // Arithmetic + boolean contains = false; + for (String s : getVars()) { + if (variables.containsKey(s)) { + contains = true; + break; + } + } + if (!contains) { + return false; + } + if (!(evaluateExpr(variables) == 0.0)) { + return false; + } + return true; + case 'n': // Number + if (uvalue == 0.0 && lvalue == 0.0) { + return true; + } + return false; + } + return false; + } + + public boolean becomesTrue(HashMap variables) { + switch (isit) { + case 'b': // Boolean + if (variables.containsKey(variable)) { + if (variables.get(variable).toString().matches("[\\d[\\.]]+")) { + if (Double.parseDouble(variables.get(variable).toString()) != 0) { + return true; + } + } + if (variables.get(variable).toString().toLowerCase().equals( + "true")) + return true; + } + return false; + case 'i': // Integer + if (variables.containsKey(variable)) { + if (!variables.get(variable).equals("0.0")) { + return true; + } + } + return false; + case 'c': // Continuous + return true; + case 'n': // Number + case 't': // Truth value + if (uvalue != 0) + return true; + return false; + case 'l': // Logical + if (op.equals("||")) { + if (r1.becomesTrue(variables) || r2.becomesTrue(variables)) + return true; + return false; + } else if (op.equals("&&")) { + if ((r1.becomesTrue(variables) && !r2.becomesFalse(variables)) + || (!r1.becomesFalse(variables) && r2 + .becomesTrue(variables))) + return true; + return false; + } else if (op.equals("==")) { + if (r1.isEqual(r2, variables) + || r1.evaluateExpr(variables) == r2 + .evaluateExpr(variables)) + return true; + return false; + } else if (op.equals("!")) { + if (r1.becomesFalse(variables)) + return true; + return false; + } else if (op.equals("->")) { + if (r1.becomesTrue(variables) || r2.becomesFalse(variables)) { + return true; + } + return false; + } + break; + case 'w': // bitWise + if (op.equals("&")) { + if (evaluateExpr(variables) == 0.0) { + return false; + } + return true; + } else if (op.equals("|")) { + if (evaluateExpr(variables) == 0.0) { + return false; + } + return true; + } else if (op.equals("X")) { + if (evaluateExpr(variables) == 0.0) { + return false; + } + return true; + } else if (op.equals("~")) { + if (evaluateExpr(variables) == 0.0) { + return false; + } + return true; + } else if (op.equals("[]")) { + if (evaluateExpr(variables) == 0.0) { + return false; + } + return true; + } + break; + case 'r': // Relational + if (r1.isit == 'i') { + if (!variables.containsKey(r1.variable)) { + return false; + } + if (op.equals("==")) { + if (!(r1.evaluateExpr(variables) == r2 + .evaluateExpr(variables))) { + return false; + } + return true; + } else if (op.equals(">=")) { + if (!(r1.evaluateExpr(variables) >= r2 + .evaluateExpr(variables))) { + return false; + } + return true; + } else if (op.equals("<=")) { + if (!(r1.evaluateExpr(variables) <= r2 + .evaluateExpr(variables))) { + return false; + } + return true; + } else if (op.equals(">")) { + if (!(r1.evaluateExpr(variables) > r2 + .evaluateExpr(variables))) { + return false; + } + return true; + } else if (op.equals("<")) { + if (!(r1.evaluateExpr(variables) < r2 + .evaluateExpr(variables))) { + return false; + } + return true; + } + return true; + } + return true; + case 'a': // Arithmetic + boolean contains = false; + for (String s : getVars()) { + if (variables.containsKey(s)) { + contains = true; + break; + } + } + if (!contains) { + return false; + } + if (!(evaluateExpr(variables) != 0.0)) { + return false; + } + return true; + } + return true; + } + + public String getElement(String type) { + boolean sbmlFlag; + sbmlFlag = type.equals("SBML"); + Boolean verilog = type.equalsIgnoreCase("Verilog"); + String result = ""; + switch (isit) { + case 'b': // Boolean + case 'i': // Integer + case 'c': // Continuous + if (!sbmlFlag) { + result = variable; + } else { + if (isit == 'b') { + result = "eq(" + variable + ",1)"; + } else { + result = variable; + } + } + break; + case 'n': // Number + // long term solution: create initial assignment + // short term solution: initialize all inf, -inf, [-inf, inf] to 0 + // initialize [l,u] to (l+u)/2 + Double tempuval = uvalue; + Double templval = lvalue; + if ((uvalue == lvalue) || tempuval.toString().equals("")) { + if (lvalue == INFIN) { + result = "inf"; + } else if (lvalue == -INFIN) { + result = "-inf"; + } else { + if (tempuval % 1 == 0) { + int tempval = (int) (tempuval / 1); + result = new Integer(tempval).toString(); + } else { + result = tempuval.toString(); + } + } + } else { + String lval; + if (lvalue == INFIN) { + lval = "inf"; + } else if (lvalue == -INFIN) { + lval = "-inf"; + } else { + if (tempuval % 1 == 0) { + int tempval = (int) (templval / 1); + lval = new Integer(tempval).toString(); + } else { + lval = templval.toString(); + } + } + String uval; + if (uvalue == INFIN) { + uval = "inf"; + } else if (uvalue == -INFIN) { + uval = "-inf"; + } else { + if (tempuval % 1 == 0) { + int tempval = (int) (tempuval / 1); + uval = new Integer(tempval).toString(); + } else { + uval = tempuval.toString(); + } + } + if (verilog) { + result = "uniform(" + lval + "," + uval + ")"; + } else { + result = "uniform(" + lval + "," + uval + ")"; + } + } + break; + case 't': // Truth value + if (uvalue == 0 && lvalue == 0) { + if (verilog) + result = "0"; + else + result = "FALSE"; + } else if (uvalue == 1 && lvalue == 1) { + if (verilog) + result = "1"; + else + result = "TRUE"; + } else { + if (sbmlFlag) + result = "TRUE"; + else + result = "UNKNOWN"; + } + break; + + case 'w': // bitWise + if (op.equals("&")) { + if (r1 != null && r2 != null) { + if (sbmlFlag) { + result = "BITAND(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } else if (verilog) { + result = r1.getElement(type) + "&" + + r2.getElement(type); + } else { + result = "and(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + } + } else if (op.equals("|")) { + if (r1 != null && r2 != null) { + if (sbmlFlag) { + result = "BITOR(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } else if (verilog) { + result = r1.getElement(type) + "|" + + r2.getElement(type); + } else { + result = "or(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + } + } else if (op.equals("!")) { + if (r1 != null && r2 != null) { + if (sbmlFlag) { + result = "BITNOT(" + r1.getElement(type) + ")"; + } else if (verilog) { + result = "~" + r1.getElement(type); + } else { + result = "not(" + r1.getElement(type) + ")"; + } + + } + } else if (op.equals("X")) { + if (r1 != null && r2 != null) { + if (sbmlFlag) { + result = "XOR(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } else if (verilog) { + result = r1.getElement(type) + "^" + + r2.getElement(type); + } else { + result = "exor(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + + } + } + break; + case 'a': // Arithmetic + case 'r': // Relational + case 'l': // Logical + if (op.equals("!")) { + if (r1 != null) { + if (r1.isit == 'b' || r1.isit == 'i' || r1.isit == 'c' + || r1.isit == 'n' || r1.isit == 't') { + if (sbmlFlag) { + result = "not(" + r1.getElement(type) + ")"; + } else if (verilog) { + result = "!" + r1.getElement(type); + } else { + result = "~" + r1.getElement(type); + } + } else { + if (sbmlFlag) { + result = "not(" + r1.getElement(type) + ")"; + } else if (verilog) { + result = "!" + "(" + r1.getElement(type) + ")"; + } else { + result = "~" + "(" + r1.getElement(type) + ")"; + } + } + } + break; + } + if (op.equals("&&")) { + if (r1.isit == 'r' + || (r1.isit == 'l' && r1.op.equals("||"))) { + if (r1 != null) { + if (sbmlFlag) { + result = "and(" + r1.getElement(type) + ","; + } else if (verilog) { + result = "(" + r1.getElement(type) + ")&&"; + } else { + result = "(" + r1.getElement(type) + ")"; + } + } + + } else { + if (r1 != null) { + if (sbmlFlag) { + result = "and(" + r1.getElement(type) + ","; + } else if (verilog) { + result = r1.getElement(type) + "&&"; + } else { + result = r1.getElement(type); + } + + } + } + + if (!sbmlFlag && !verilog) { + result = result + "&"; + } + + if (r2.isit == 'r' + || (r2.isit == 'l' && r2.op.equals("||"))) { + if (r2 != null) { + if (sbmlFlag) { + result = result + r2.getElement(type) + ")"; + } else { + result = result + "(" + r2.getElement(type) + + ")"; + } + + } + } else { + if (r2 != null) { + if (sbmlFlag) { + result = result + r2.getElement(type) + ")"; + } else { + result = result + r2.getElement(type); + } + + } + } + } else if (op.equals("||")) { + if (r1.isit == 'r') { + if (r1 != null) { + if (sbmlFlag) { + result = "or(" + r1.getElement(type) + ","; + } else if (verilog) { + result = "(" + r1.getElement(type) + ")||"; + } else { + result = "(" + r1.getElement(type) + ")"; + } + + } + } else { + if (r1 != null) { + if (sbmlFlag) { + result = "or(" + r1.getElement(type) + ","; + } else if (verilog) { + result = r1.getElement(type) + "||"; + } else { + result = r1.getElement(type); + } + } + } + + if (!sbmlFlag && !verilog) { + result = result + "|"; + } + + if (r2.isit == 'r') { + if (r2 != null) { + if (sbmlFlag) { + result = result + r2.getElement(type) + ")"; + } else { + result = result + "(" + r2.getElement(type) + + ")"; + } + + } + } else { + if (r2 != null) { + if (sbmlFlag) { + result = result + r2.getElement(type) + ")"; + } else { + result = result + r2.getElement(type); + } + + } + } + } else if (op.equals("f")) { + if (r1 != null) { + if (r1.isit == 'n') { + result = new Integer((int) Math.floor(r1.lvalue)) + .toString(); + } else { + if (sbmlFlag) { + result = "floor(" + r1.getElement(type) + ")"; + } else if (verilog) { + result = "$floor(" + r1.getElement(type) + ")"; + } else { + result = "floor(" + r1.getElement(type) + ")"; + } + } + } + } else if (op.equals("c")) { + if (r1 != null) { + if (r1.isit == 'n') { + result = new Integer((int) Math.ceil(r1.lvalue)) + .toString(); + } else { + if (sbmlFlag) { + result = "ceil(" + r1.getElement(type) + ")"; + } else if (verilog) { + result = "$ceil(" + r1.getElement(type) + ")"; + } else { + result = "ceil(" + r1.getElement(type) + ")"; + } + } + } + } else if (op.equals("m")) { + if (r1 != null && r2 != null) { + if (r1.isit == 'n' && r2.isit == 'n') { + if (r1.lvalue < r2.lvalue) { + result = r1.getElement(type); + } else { + result = r2.getElement(type); + } + } else { + if (sbmlFlag) { + result = "piecewise(" + r1.getElement(type) + + ",leq(" + r1.getElement(type) + "," + + r2.getElement(type) + ")," + + r2.getElement(type) + ")"; + //} else if (verilog) { + //result = "min(" + r1.getElement(type) + "," + // + r2.getElement(type) + ")"; + } else if (verilog) { + result = "("+r1.getElement(type) +"<"+r2.getElement(type) +"?"+r1.getElement(type) +":"+r2.getElement(type) +")"; + } else { + result = "min(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + } + + } + } else if (op.equals("M")) { + if (r1 != null && r2 != null) { + if (r1.isit == 'n' && r2.isit == 'n') { + if (r1.lvalue > r2.lvalue) { + result = r1.getElement(type); + } else { + result = r2.getElement(type); + } + } else { + if (sbmlFlag) { + result = "piecewise(" + r1.getElement(type) + + ",geq(" + r1.getElement(type) + "," + + r2.getElement(type) + ")," + + r2.getElement(type) + ")"; + //} else if (verilog) { + //result = "max(" + r1.getElement(type) + "," + //+ r2.getElement(type) + ")"; + } else if (verilog) { + result = "("+r1.getElement(type) +">"+r2.getElement(type) +"?"+r1.getElement(type) +":"+r2.getElement(type) +")"; + } else { + result = "max(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + } + } + } else if (op.equals("i")) { + if (r1 != null && r2 != null) { + if (sbmlFlag) { + result = "floor(" + r1.getElement(type) + "/" + + r2.getElement(type) + ")"; + } else if (verilog) { + result = "floor(" + r1.getElement(type) + "/" + + r2.getElement(type) + ")"; + } else { + result = "idiv(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + + } + } else if (op.equals("uniform")) { + if (r1 != null && r2 != null) { + if (verilog) { + result = "uniform(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } else { + result = "uniform(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + } + } // TODO: Add verilog functions for other distributions + else if (op.equals("[]")) { + if (r1 != null && r2 != null) { + result = "BIT(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + } else if (op.equals("normal")) { + if (r1 != null && r2 != null) { + result = "normal(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + } else if (op.equals("gamma")) { + if (r1 != null && r2 != null) { + result = "gamma(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + } else if (op.equals("lognormal")) { + if (r1 != null && r2 != null) { + result = "lognormal(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + } else if (op.equals("binomial")) { + if (r1 != null && r2 != null) { + result = "binomial(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + } else if (op.equals("exponential")) { + if (r1 != null) { + result = "exponential(" + r1.getElement(type) + ")"; + } + } else if (op.equals("chisq")) { + if (r1 != null) { + result = "chisq(" + r1.getElement(type) + ")"; + } + } else if (op.equals("laplace")) { + if (r1 != null) { + result = "laplace(" + r1.getElement(type) + ")"; + } + } else if (op.equals("cauchy")) { + if (r1 != null) { + result = "cauchy(" + r1.getElement(type) + ")"; + } + } else if (op.equals("rayleigh")) { + if (r1 != null) { + result = "rayleigh(" + r1.getElement(type) + ")"; + } + } else if (op.equals("poisson")) { + if (r1 != null) { + result = "poisson(" + r1.getElement(type) + ")"; + } + } else if (op.equals("bernoulli")) { + if (r1 != null) { + result = "bernoulli(" + r1.getElement(type) + ")"; + } + } else if (op.equals("rate")) { + if (r1 != null) { + result = "rate(" + r1.getElement(type) + ")"; + } + } else if (op.equals("INT")) { + if (r1 != null) { + if (sbmlFlag) { + result = "piecewise(1," + r1.getElement(type) + + ",0 )"; + } else { + result = "INT(" + r1.getElement(type) + ")"; + } + + } + } else if (op.equals("==")) { + if (r1 != null) { + if (sbmlFlag) { + result = "eq(" + r1.getElement(type) + ","; + } else if (verilog) { + result = r1.getElement(type) + "=="; + } else { + result = r1.getElement(type); + } + + } + if (!sbmlFlag && !verilog) { + result = result + "="; + } + + if (r2 != null) { + if (sbmlFlag) { + result = result + r2.getElement(type) + ")"; + } else { + result = result + r2.getElement(type); + } + + } + } else if (op.equals("+")) { + if (r1.isit == 'n' && r1.lvalue >= 0 && r2.isit == 'a' + && r2.op.equals("uniform")) { + ExprTree tempUniform = new ExprTree(r2); + r1.setNodeValues(r1, tempUniform.r1, "+", 'a'); + r2.setNodeValues(r1, tempUniform.r2, "+", 'a'); + isit = 'a'; + op = "uniform"; + } else if (r1.isit == 'a' && r1.op.equals("uniform") + && r2.isit == 'n' && r2.lvalue >= 0) { + ExprTree tempUniform = new ExprTree(r1); + r1.setNodeValues(r2, tempUniform.r1, "+", 'a'); + r2.setNodeValues(r2, tempUniform.r2, "+", 'a'); + isit = 'a'; + op = "uniform"; + } else { + try { + String r1String = r1.getElement(type); + String r2String = r2.getElement(type); + result = new Float(Float.parseFloat(r1String) + + Float.parseFloat(r2String)).toString(); + } catch (NumberFormatException e) { + if (r1.isit == 'b' + || r1.isit == 'i' + || r1.isit == 'c' + || r1.isit == 'n' + || r1.isit == 't' + || (r1.isit == 'a' && (r1.op.equals("+") + || r1.op.equals("-") + || r1.op.equals("*") + || r1.op.equals("/") || r1.op + .equals("^")))) { + if (r1 != null) { + result = r1.getElement(type); + } + } else { + if (r1 != null) { + result = "(" + r1.getElement(type) + ")"; + } + } + result = result + "+"; + if (r2.isit == 'b' + || r2.isit == 'i' + || r2.isit == 'c' + || r2.isit == 'n' + || r2.isit == 't' + || (r2.isit == 'a' && (r2.op.equals("+") + || r2.op.equals("-") + || r2.op.equals("*") + || r2.op.equals("/") || r2.op + .equals("^")))) { + if (r2 != null) { + result = result + r2.getElement(type); + } + } else { + if (r2 != null) { + result = result + "(" + r2.getElement(type) + + ")"; + } + } + } + } + } else if (op.equals("-")) { + if (r1.isit == 'a' && r1.op.equals("uniform") + && r2.isit == 'n' && r2.lvalue >= 0) { + ExprTree tempUniform = new ExprTree(r1); + r1.setNodeValues(tempUniform.r1, r2, "-", 'a'); + r2.setNodeValues(tempUniform.r2, r2, "-", 'a'); + isit = 'a'; + op = "uniform"; + } else { + try { + String r1String = r1.getElement(type); + String r2String = r2.getElement(type); + result = new Float(Float.parseFloat(r1String) + - Float.parseFloat(r2String)).toString(); + } catch (NumberFormatException e) { + if (r1.isit == 'b' + || r1.isit == 'i' + || r1.isit == 'c' + || r1.isit == 'n' + || r1.isit == 't' + || (r1.isit == 'a' && (r1.op.equals("+") + || r1.op.equals("-") + || r1.op.equals("*") + || r1.op.equals("/") || r1.op + .equals("^")))) { + if (r1 != null) { + result = r1.getElement(type); + } + } else { + if (r1 != null) { + result = "(" + r1.getElement(type) + ")"; + } + } + result = result + "-"; + if (r2.isit == 'b' + || r2.isit == 'i' + || r2.isit == 'c' + || r2.isit == 'n' + || r2.isit == 't' + || (r2.isit == 'a' && (r2.op.equals("-") + || r2.op.equals("*") + || r2.op.equals("/") || r2.op + .equals("^")))) { + if (r2 != null) { + result = result + r2.getElement(type); + } + } else { + if (r2 != null) { + result = result + "(" + r2.getElement(type) + + ")"; + } + } + } + } + } else if (op.equals("*")) { + if (r1.isit == 'n' && r1.lvalue >= 0 && r2.isit == 'a' + && r2.op.equals("uniform")) { + ExprTree tempUniform = new ExprTree(r2); + r1.setNodeValues(r1, tempUniform.r1, "*", 'a'); + r2.setNodeValues(r1, tempUniform.r2, "*", 'a'); + isit = 'a'; + op = "uniform"; + } else if (r1.isit == 'a' && r1.op.equals("uniform") + && r2.isit == 'n' && r2.lvalue >= 0) { + ExprTree tempUniform = new ExprTree(r1); + r1.setNodeValues(r2, tempUniform.r1, "*", 'a'); + r2.setNodeValues(r2, tempUniform.r2, "*", 'a'); + isit = 'a'; + op = "uniform"; + } else { + try { + String r1String = r1.getElement(type); + String r2String = r2.getElement(type); + result = new Float(Float.parseFloat(r1String) + * Float.parseFloat(r2String)).toString(); + } catch (NumberFormatException e) { + if (r1.isit == 'b' + || r1.isit == 'i' + || r1.isit == 'c' + || r1.isit == 'n' + || r1.isit == 't' + || (r1.isit == 'a' && (r1.op.equals("*") + || r1.op.equals("/") || r1.op + .equals("^")))) { + if (r1 != null) { + result = r1.getElement(type); + } + } else { + if (r1 != null) { + result = "(" + r1.getElement(type) + ")"; + } + } + result = result + "*"; + if (r2.isit == 'b' + || r2.isit == 'i' + || r2.isit == 'c' + || r2.isit == 'n' + || r2.isit == 't' + || (r2.isit == 'a' && (r2.op.equals("*") + || r2.op.equals("/") || r2.op + .equals("^")))) { + if (r2 != null) { + result = result + r2.getElement(type); + } + } else { + if (r2 != null) { + result = result + "(" + r2.getElement(type) + + ")"; + } + } + } + } + } else if (op.equals("/")) { + if (r1.isit == 'a' && r1.op.equals("uniform") + && r2.isit == 'n' && r2.lvalue >= 0) { + ExprTree tempUniform = new ExprTree(r1); + r1.setNodeValues(tempUniform.r1, r2, "/", 'a'); + r2.setNodeValues(tempUniform.r2, r2, "/", 'a'); + isit = 'a'; + op = "uniform"; + } else { + try { + String r1String = r1.getElement(type); + String r2String = r2.getElement(type); + result = new Float(Float.parseFloat(r1String) + / Float.parseFloat(r2String)).toString(); + } catch (NumberFormatException e) { + if (r1.isit == 'b' + || r1.isit == 'i' + || r1.isit == 'c' + || r1.isit == 'n' + || r1.isit == 't' + || (r1.isit == 'a' && (r1.op.equals("*") + || r1.op.equals("/") || r1.op + .equals("^")))) { + if (r1 != null) { + result = r1.getElement(type); + } + } else { + if (r1 != null) { + result = "(" + r1.getElement(type) + ")"; + } + } + result = result + "/"; + if (r2.isit == 'b' + || r2.isit == 'i' + || r2.isit == 'c' + || r2.isit == 'n' + || r2.isit == 't' + || (r2.isit == 'a' && (r2.op.equals("/") || r2.op + .equals("^")))) { + if (r2 != null) { + result = result + r2.getElement(type); + } + } else { + if (r2 != null) { + result = result + "(" + r2.getElement(type) + + ")"; + } + } + } + } + } else if (op.equals("^")) { + try { + String r1String = r1.getElement(type); + String r2String = r2.getElement(type); + result = new Integer(Integer.parseInt(r1String) + ^ Integer.parseInt(r2String)).toString(); + } catch (NumberFormatException e) { + if (r1.isit == 'b' + || r1.isit == 'i' + || r1.isit == 'c' + || r1.isit == 'n' + || r1.isit == 't' + || (r1.isit == 'a' && (r1.op.equals("*") + || r1.op.equals("/") || r1.op + .equals("^")))) { + if (r1 != null) { + result = "(" + r1.getElement(type) + ")"; + } + } else { + if (r1 != null) { + result = "(" + r1.getElement(type) + ")"; + } + } + if (type.equals("prism")) result = "pow(" + result + ","; + else result = result + "^"; + if (r2.isit == 'b' + || r2.isit == 'i' + || r2.isit == 'c' + || r2.isit == 'n' + || r2.isit == 't' + || (r2.isit == 'a' && (r2.op.equals("/") || r2.op + .equals("^")))) { + if (r2 != null) { + result = result + "(" + r2.getElement(type) + + ")"; + } + } else { + if (r2 != null) { + result = result + "(" + r2.getElement(type) + + ")"; + } + } + if (type.equals("prism")) result = result + ")"; + } + } + // relational ops: geq, leq, gt, lt + // mod + else { + if (!sbmlFlag) { + if (r1 != null) { + if (r1.isit == 'b' || r1.isit == 'i' + || r1.isit == 'c' || r1.isit == 'n' + || r1.isit == 't') { + result = r1.getElement(type); + } else { + result = "(" + r1.getElement(type) + ")"; + } + } + result = result + op; + if (r2 != null) { + if (r2.isit == 'b' || r2.isit == 'i' + || r2.isit == 'c' || r2.isit == 'n' + || r2.isit == 't') { + result = result + r2.getElement(type); + } else { + result = result + "(" + r2.getElement(type) + + ")"; + } + } + } + + if (sbmlFlag) { + if (op.equals("<=")) { + if (r1 != null && r2 != null) { + result = "leq(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + } + if (op.equals(">=")) { + if (r1 != null && r2 != null) { + result = "geq(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + } + if (op.equals(">")) { + if (r1 != null && r2 != null) { + result = "gt(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + } + if (op.equals("<")) { + if (r1 != null && r2 != null) { + result = "lt(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + } + if (op.equals("%")) { + if (r1 != null && r2 != null) { + result = "mod(" + r1.getElement(type) + "," + + r2.getElement(type) + ")"; + } + } + + } + } + } + return result; + } + + public ExprTree minimizeUniforms() { + if (r1 != null) { + r1.minimizeUniforms(); + } + if (r2 != null) { + r2.minimizeUniforms(); + } + if (isit == 'a' && op.equals("m")) { + if (r1.isit == 'n' && r2.isit == 'n') { + isit = 'n'; + if (r1.lvalue < r2.lvalue) { + lvalue = r1.lvalue; + } else { + lvalue = r2.lvalue; + } + r1 = null; + r2 = null; + } else if (r1.isit == 'a' && r1.op.equals("uniform") + && r2.isit == 'a' && r2.op.equals("uniform")) { + ExprTree l1 = r1.r1; + ExprTree l2 = r2.r1; + ExprTree u1 = r1.r2; + ExprTree u2 = r2.r2; + op = "uniform"; + r1.op = "m"; + r2.op = "m"; + r1.r1 = l1; + r1.r2 = l2; + r2.r1 = u1; + r2.r2 = u2; + } + } + if (isit == 'a' && op.equals("M")) { + if (r1.isit == 'n' && r2.isit == 'n') { + isit = 'n'; + if (r1.lvalue < r2.lvalue) { + lvalue = r2.lvalue; + } else { + lvalue = r1.lvalue; + } + r1 = null; + r2 = null; + } else if (r1.isit == 'a' && r1.op.equals("uniform") + && r2.isit == 'a' && r2.op.equals("uniform")) { + ExprTree l1 = r1.r1; + ExprTree l2 = r2.r1; + ExprTree u1 = r1.r2; + ExprTree u2 = r2.r2; + op = "uniform"; + r1.op = "M"; + r2.op = "M"; + r1.r1 = l1; + r1.r2 = l2; + r2.r1 = u1; + r2.r2 = u2; + } + } + if (isit == 'a' && op.equals("+")) { + if (r1.isit == 'a' && r1.op.equals("uniform") && r2.isit == 'a' + && r2.op.equals("uniform")) { + ExprTree l1 = r1.r1; + ExprTree l2 = r2.r1; + ExprTree u1 = r1.r2; + ExprTree u2 = r2.r2; + op = "uniform"; + r1.op = "+"; + r2.op = "+"; + r1.r1 = l1; + r1.r2 = l2; + r2.r1 = u1; + r2.r2 = u2; + } + } + if (isit == 'a' && op.equals("-")) { + if (r1.isit == 'a' && r1.op.equals("uniform") && r2.isit == 'a' + && r2.op.equals("uniform")) { + ExprTree l1 = r1.r1; + ExprTree l2 = r2.r1; + ExprTree u1 = r1.r2; + ExprTree u2 = r2.r2; + op = "uniform"; + r1.op = "+"; + r2.op = "+"; + r1.r1 = l1; + r1.r2 = u2; + r2.r1 = u1; + r2.r2 = l2; + } + } + if (isit == 'a' && op.equals("c")) { + if (r1.isit == 'a' && r1.op.equals("uniform")) { + ExprTree l1 = r1.r1; + ExprTree u1 = r1.r2; + op = "uniform"; + r1 = new ExprTree(l1, null, "c", 'a'); + r2 = new ExprTree(u1, null, "c", 'a'); + } + } + if (isit == 'a' && op.equals("f")) { + if (r1.isit == 'a' && r1.op.equals("uniform")) { + ExprTree l1 = r1.r1; + ExprTree u1 = r1.r2; + op = "uniform"; + r1 = new ExprTree(l1, null, "f", 'a'); + r2 = new ExprTree(u1, null, "f", 'a'); + } + } + if (isit == 'a' && op.equals("uniform")) { + if (r1.isit == 'a' && r1.op.equals("uniform")) { + r1 = r1.r1; + } + if (r2.isit == 'a' && r2.op.equals("uniform")) { + r2 = r2.r2; + } + } + return this; + } + + public boolean isEqual(ExprTree expr) { + if (isit == expr.isit) { + boolean same = false; + switch (isit) { + case 'b': // Boolean + case 'i': // Integer + case 'c': // Continuous + if (variable.equals(expr.variable)) { + same = true; + } + break; + case 'n': // Number + case 't': // Truth value + if (uvalue == expr.uvalue && lvalue == expr.lvalue) { + same = true; + } + break; + case 'w': // bitWise + case 'a': // Arithmetic + case 'r': // Relational + case 'l': // Logical + if (op.equals(expr.op)) { + same = true; + } + } + if (same) { + boolean r1Same = false, r2Same = false; + if (r1 == null) { + if (expr.r1 == null) { + r1Same = true; + } + } else if (r1.isEqual(expr.r1)) { + r1Same = true; + } + if (r2 == null) { + if (expr.r2 == null) { + r2Same = true; + } + } else if (r2.isEqual(expr.r2)) { + r2Same = true; + } + if (r1Same && r2Same) { + return true; + } + } + } + return false; + } + + private boolean isEqual(ExprTree expr, HashMap variables) { + if (isit == expr.isit) { + boolean same = false; + switch (isit) { + case 'b': // Boolean + case 'i': // Integer + case 'c': // Continuous + if (variables.containsKey(variable)) { + if (variables.containsKey(expr.variable)) { + if (variables.get(variable).equals( + variables.get(expr.variable))) + same = true; + } + } else if (variable.equals(expr.variable)) { + same = true; + } + break; + case 'n': // Number + case 't': // Truth value + if (uvalue == expr.uvalue && lvalue == expr.lvalue) { + same = true; + } else if (variables.containsKey(expr.variable)) { + if (uvalue == lvalue) { + if (uvalue == 1.0 + && variables.get(expr.variable).toLowerCase() + .equals("true")) + same = true; + else if (uvalue == 0.0 + && variables.get(expr.variable).toLowerCase() + .equals("false")) + same = true; + } + } + break; + case 'w': // bitWise + case 'a': // Arithmetic + case 'r': // Relational + case 'l': // Logical + if (op.equals(expr.op)) { + same = true; + } + } + if (same) { + boolean r1Same = false, r2Same = false; + if (r1 == null) { + if (expr.r1 == null) { + r1Same = true; + } + } else if (r1.isEqual(expr.r1)) { + r1Same = true; + } + if (r2 == null) { + if (expr.r2 == null) { + r2Same = true; + } + } else if (r2.isEqual(expr.r2)) { + r2Same = true; + } + if (r1Same && r2Same) { + return true; + } + } + } + return false; + } + + private void setVarValues(char willbe, double lNV, double uNV, String var) { + op = ""; + r1 = null; + r2 = null; + isit = willbe; + if ((isit == 'b') || (isit == 't')) + logical = true; + else + logical = false; + uvalue = uNV; + lvalue = lNV; + variable = var; + real = 0; + } + + public void setNodeValues(ExprTree nr1, ExprTree nr2, String nop, + char willbe) { + ExprTree r1temp = null, r2temp = null; + if (nr1 != null) { + r1temp = new ExprTree(nr1); + } + if (nr2 != null) { + r2temp = new ExprTree(nr2); + } + r1 = r1temp; + r2 = r2temp; + op = nop; + isit = willbe; + if ((isit == 'r') || (isit == 'l')) { + logical = true; + uvalue = 1; + lvalue = 0; + } else { + logical = false; + uvalue = INFIN; + lvalue = -INFIN; + } + variable = null; + // simplify if operands are static + if (isit == 'a' || isit == 'r' || isit == 'l' || isit == 'w') { + if (op.equals("&&")) { + if ((r1.isit == 'n') || (r1.isit == 't')) { + if (r1.lvalue == 0) { + setVarValues('t', 0.0, 0.0, null); + } else { + if (r2.isit == 'l' || r2.isit == 'a' || r2.isit == 'w' + || r2.isit == 'r') { + setNodeValues(r2.r1, r2.r2, r2.op, r2.isit); + } else { + setVarValues(r2.isit, r2.lvalue, r2.uvalue, + r2.variable); + } + } + } else if (((r2).isit == 'n') || ((r2).isit == 't')) { + if (r2.lvalue == 0) { + setVarValues('t', 0.0, 0.0, null); + } else { + if (r1.isit == 'l' || r1.isit == 'a' || r1.isit == 'w' + || r1.isit == 'r') { + setNodeValues(r1.r1, r1.r2, r1.op, r1.isit); + } else { + setVarValues(r1.isit, r1.lvalue, r1.uvalue, + r1.variable); + } + } + } else if (r1.equals(r2)) { + if (r1.isit == 'l' || r1.isit == 'a' || r1.isit == 'w' + || r1.isit == 'r') { + setNodeValues(r1.r1, r1.r2, r1.op, r1.isit); + } else { + setVarValues(r1.isit, r1.lvalue, r1.uvalue, r1.variable); + } + } else { + ExprTree notE = new ExprTree(this); + notE.setNodeValues((this), null, "!", 'l'); + if (r1.equals(notE) || notE.equals(r1)) { + setVarValues('t', 0.0, 0.0, null); + } + } + } else if (op.equals("||")) { + if ((r1.isit == 'n') || (r1.isit == 't')) { + if (r1.lvalue != 0) { + setVarValues('t', 1.0, 1.0, null); + } else { + if (r2.isit == 'l' || r2.isit == 'a' || r2.isit == 'w' + || r2.isit == 'r') { + setNodeValues(r2.r1, r2.r2, r2.op, r2.isit); + } else { + setVarValues(r2.isit, r2.lvalue, r2.uvalue, + r2.variable); + } + } + } else if (((r2).isit == 'n') || ((r2).isit == 't')) { + if (r2.lvalue != 0) { + setVarValues('t', 1.0, 1.0, null); + } else { + if (r1.isit == 'l' || r1.isit == 'a' || r1.isit == 'w' + || r1.isit == 'r') { + setNodeValues(r1.r1, r1.r2, r1.op, r1.isit); + } else { + setVarValues(r1.isit, r1.lvalue, r1.uvalue, + r1.variable); + } + } + } else if (r1.equals(r2)) { + if (r1.isit == 'l' || r1.isit == 'a' || r1.isit == 'w' + || r1.isit == 'r') { + setNodeValues(r1.r1, r1.r2, r1.op, r1.isit); + } else { + setVarValues(r1.isit, r1.lvalue, r1.uvalue, r1.variable); + } + } else { + ExprTree notE = new ExprTree(this); + notE.setNodeValues((this), null, "!", 'l'); + if (r1.equals(notE) || notE.equals(r1)) { + setVarValues('t', 1.0, 1.0, null); + } + } + } else if (op.equals("->")) { + if (r1.isit == 'n' || r1.isit == 't') { + if (r1.lvalue != 0) { + if (r2.isit == 'l' || r2.isit == 'a' || r2.isit == 'w' + || r2.isit == 'r') { + setNodeValues(r2.r1, r2.r2, r2.op, r2.isit); + } else { + setVarValues(r2.isit, r2.lvalue, r2.uvalue, + r2.variable); + } + } else if (r1.uvalue == 0) { + setVarValues('t', 1.0, 1.0, null); + } + } else if (r2.isit == 't' || r2.isit == 'n') { + if (r2.lvalue != 0) { + setVarValues('t', 1.0, 1.0, null); + } else if (r2.uvalue == 0) { + ExprTree notE = new ExprTree(r2); + notE.setNodeValues((this), null, "!", 'l'); + setNodeValues(notE.r1, notE.r2, notE.op, notE.isit); + } + } + } else if (op.equals("!")) { + if (((r1).isit == 'n') || ((r1).isit == 't')) { + (this).isit = 't'; + if (r1.lvalue == 1) { + this.lvalue = 0; + } else { + this.lvalue = 1; + } + (this).uvalue = (this).lvalue; + } + } else if (op.equals("==")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 't'; + if (r1.lvalue == r2.lvalue) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + } + } else if (op.equals(">=")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 't'; + if ((r1).lvalue >= r2.lvalue) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + } + } else if (op.equals(">")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 't'; + if ((r1).lvalue > r2.lvalue) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + } + } else if (op.equals("<=")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 't'; + if ((r1).lvalue <= r2.lvalue) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + } + } else if (op.equals("<")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 't'; + if ((r1).lvalue < r2.lvalue) { + this.lvalue = 1; + } else { + this.lvalue = 0; + } + (this).uvalue = (this).lvalue; + } + } else if (op.equals("&")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = ((int) (r1).lvalue) & ((int) r2.lvalue); + (this).uvalue = (this).lvalue; + } + } else if (op.equals("|")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = (int) (r1).lvalue | (int) r2.lvalue; + (this).uvalue = (this).lvalue; + } + } else if (isit == 'w' && op.equals("X")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = (int) (r1).lvalue ^ (int) r2.lvalue; + (this).uvalue = (this).lvalue; + } + } else if (op.equals("m")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = Math.min((r1).lvalue, r2.lvalue); + (this).uvalue = (this).lvalue; + } + } else if (op.equals("M")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = Math.max((r1).lvalue, r2.lvalue); + (this).uvalue = (this).lvalue; + } + } else if (op.equals("i")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = Math.floor((r1).lvalue / r2.lvalue); + (this).uvalue = (this).lvalue; + } + } else if (op.equals("f")) { + if (((r1).isit == 'n') || ((r1).isit == 't')) { + (this).isit = 'n'; + (this).lvalue = Math.floor((r1).lvalue); + (this).uvalue = (this).lvalue; + } + } else if (op.equals("c")) { + if (((r1).isit == 'n') || ((r1).isit == 't')) { + (this).isit = 'n'; + (this).lvalue = Math.ceil((r1).lvalue); + (this).uvalue = (this).lvalue; + } + } else if (op.equals("~")) { + if (((r1).isit == 'n') || ((r1).isit == 't')) { + (this).isit = 'n'; + (this).lvalue = ~(int) (r1).lvalue; + (this).uvalue = (this).lvalue; + } + } else if (op.equals("[]")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 't'; + (this).lvalue = (((int) (r1).lvalue) >> ((int) r2.lvalue)) & 1; + (this).uvalue = (this).lvalue; + } + } else if (op.equals("U-")) { + if (((r1).isit == 'n') || ((r1).isit == 't')) { + (this).isit = 'n'; + (this).lvalue = -((r1).lvalue); + (this).uvalue = (this).lvalue; + } + } else if (op.equals("*")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = (r1).lvalue * r2.lvalue; + (this).uvalue = (this).lvalue; + } else if (r1.isit == 'n' || r1.isit == 't') { + if (r1.lvalue == 0 && r1.uvalue == 0) { + setVarValues('t', 0.0, 0.0, null); + } else if (r1.lvalue == 1 && r1.uvalue == 1) { + if (r2.isit == 'l' || r2.isit == 'a' || r2.isit == 'w' + || r2.isit == 'r') { + setNodeValues(r2.r1, r2.r2, r2.op, r2.isit); + } else { + setVarValues(r2.isit, r2.lvalue, r2.uvalue, + r2.variable); + } + } + } else if (r2.isit == 'n' || r2.isit == 't') { + if (r2.lvalue == 0 && r2.uvalue == 0) { + setVarValues('t', 0.0, 0.0, null); + } else if (r2.lvalue == 1 && r2.uvalue == 1) { + if (r1.isit == 'l' || r1.isit == 'a' || r1.isit == 'w' + || r1.isit == 'r') { + setNodeValues(r1.r1, r1.r2, r1.op, r1.isit); + } else { + setVarValues(r1.isit, r1.lvalue, r1.uvalue, + r1.variable); + } + } + } + } else if (op.equals("/")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = (r1).lvalue / r2.lvalue; + (this).uvalue = (this).lvalue; + } else if ((r1.isit == 'n' || r1.isit == 't') && r1.uvalue == 0 + && r1.lvalue == 0) { + setVarValues('n', 0.0, 0.0, null); + } else if ((r2.isit == 'n' || r2.isit == 't') && r2.lvalue == 1 + && r2.uvalue == 1) { + if (r1.isit == 'l' || r1.isit == 'a' || r1.isit == 'w' + || r1.isit == 'r') { + setNodeValues(r1.r1, r1.r2, r1.op, r1.isit); + } else { + setVarValues(r1.isit, r1.lvalue, r1.uvalue, r1.variable); + } + } + } else if (op.equals("%")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = (r1).lvalue % r2.lvalue; + (this).uvalue = (this).lvalue; + } else if ((r2.isit == 'n' || r2.isit == 't') + && r2.lvalue == 1.0 && r2.uvalue == 1.0) { + setVarValues('n', 0.0, 0.0, null); + } else if ((r1.isit == 'n' || r1.isit == 't') + && r1.lvalue == 1.0 && r1.uvalue == 1.0) { + setVarValues('n', 1.0, 1.0, null); + } + } else if (op.equals("+")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = (r1).lvalue + r2.lvalue; + (this).uvalue = (this).lvalue; + } else if ((r1.isit == 'n' || r1.isit == 't') && r1.lvalue == 0 + && r1.uvalue == 0) { + if (r2.isit == 'l' || r2.isit == 'a' || r2.isit == 'w' + || r2.isit == 'r') { + setNodeValues(r2.r1, r2.r2, r2.op, r2.isit); + } else { + setVarValues(r2.isit, r2.lvalue, r2.uvalue, r2.variable); + } + } else if ((r2.isit == 'n' || r2.isit == 't') && r2.lvalue == 0 + && r2.uvalue == 0) { + if (r1.isit == 'l' || r1.isit == 'a' || r1.isit == 'w' + || r1.isit == 'r') { + setNodeValues(r1.r1, r1.r2, r1.op, r1.isit); + } else { + setVarValues(r1.isit, r1.lvalue, r1.uvalue, r1.variable); + } + } + } else if (op.equals("-")) { + if (((r1.isit == 'n') || (r1.isit == 't')) + && (((r2).isit == 'n') || ((r2).isit == 't'))) { + (this).isit = 'n'; + (this).lvalue = (r1).lvalue - r2.lvalue; + (this).uvalue = (this).lvalue; + } else if ((r1.isit == 'n' || r1.isit == 't') && r1.lvalue == 0 + && r1.uvalue == 0) { + setNodeValues(r2, null, "U-", 'a'); + } else if ((r2.isit == 'n' || r2.isit == 't') && r2.lvalue == 0 + && r2.uvalue == 0) { + if (r1.isit == 'l' || r1.isit == 'a' || r1.isit == 'w' + || r1.isit == 'r') { + setNodeValues(r1.r1, r1.r2, r1.op, r1.isit); + } else { + setVarValues(r1.isit, r1.lvalue, r1.uvalue, r1.variable); + } + } + } + } + } + + public double evaluateExpr(HashMap variables) { + double left; + double right; + switch (isit) { + case 'b': // Boolean + if (variables != null) { + if (!variables.containsKey(variable) + || variables.get(variable).toLowerCase().equals( + "unknown")) + return Double.NaN; + if (variables.get(variable).toLowerCase().equals("true") || + variables.get(variable).equals("1")) { + return 1.0; + } + return 0.0; + } + return Double.NaN; + case 'c': // Continuous + return Double.NaN; + case 'i': // Integer + if (variables != null) { + try { + return Double.parseDouble(variables.get(variable)); + } catch (Exception e) { + return Double.NaN; + } + } + return Double.NaN; + case 'n': // Number + if (uvalue == lvalue) { + return uvalue; + } + return ((uvalue - lvalue) * new java.util.Random().nextDouble()) + + lvalue; + case 't': // Truth value + if (uvalue == 1 && lvalue == 1) { + return 1.0; + } else if (uvalue == 0 && lvalue == 0) { + return 0.0; + } else { + return Double.NaN; + } + case 'w': // bitWise + if (r1 != null) { + left = r1.evaluateExpr(variables); + } else { + left = Double.NaN; + } + if (r2 != null) { + right = r2.evaluateExpr(variables); + } else { + right = Double.NaN; + } + if (op.equals("&")) { + return ((int) left) & ((int) right); + } else if (op.equals("|")) { + return ((int) left) | ((int) right); + } else if (op.equals("!")) { + return ~((int) left); + } else if (op.equals("X")) { + return ((int) left) ^ ((int) right); + } + break; + case 'a': // Arithmetic + case 'r': // Relational + case 'l': // Logical + if (op.equals("!")) { + if (r1 != null) { + if (r1.evaluateExpr(variables) == 1.0) { + return 0.0; + } else if (r1.evaluateExpr(variables) == 0.0) { + return 1.0; + } else { + return Double.NaN; + } + } else if (r2 != null) { + if (r2.evaluateExpr(variables) == 1.0) { + return 0.0; + } else if (r2.evaluateExpr(variables) == 0.0) { + return 1.0; + } else { + return Double.NaN; + } + } else { + return Double.NaN; + } + } + if (r1 != null) { + left = r1.evaluateExpr(variables); + } else { + left = Double.NaN; + } + if (r2 != null) { + right = r2.evaluateExpr(variables); + } else { + right = Double.NaN; + } + if (op.equals("&&")) { + if (left == 1.0 && right == 1.0) { + return 1.0; + } else if (left == 0.0 || right == 0.0) { + return 0.0; + } else + return Double.NaN; + } else if (op.equals("||")) { + if (left == 1.0 || right == 1.0) { + return 1.0; + } else if (left == 0.0 && right == 0.0) { + return 0.0; + } else + return Double.NaN; + } else if (op.equals("==")) { + if (left == Double.NaN || right == Double.NaN) { + return Double.NaN; + } else if (left == right) { + return 1.0; + } else if (left != right) { + return 0.0; + } else { + return Double.NaN; + } + } else if (op.equals("->")) { + if (left == 0.0 && (right == 1.0 || right == 0.0)) { + return 1.0; + } else if (left == 1.0 && right == 1.0) { + return 1.0; + } else if (left == 1.0 && right == 0.0) { + return 0.0; + } else { + return Double.NaN; + } + } else if (op.equals("+")) { + return left + right; + } else if (op.equals("*")) { + return left * right; + } else if (op.equals("/")) { + return left / right; + } else if (op.equals("%")) { + return left % right; + } else if (op.equals("^")) { + return Math.pow(left, right); + } else if (op.equals("[]")) { + return (((int) left) >> ((int) right)) & 1; + } else if (op.equals("f")) { + return Math.floor(left); + } else if (op.equals("c")) { + return Math.ceil(left); + } else if (op.equals("m")) { + return Math.min(left, right); + } else if (op.equals("M")) { + return Math.max(left, right); + } else if (op.equals("i")) { + return ((int) left) / ((int) right); + } else if (op.equals("uniform")) { + return Double.NaN; + } else if (op.equals("normal")) { + return Double.NaN; + } else if (op.equals("gamma")) { + return Double.NaN; + } else if (op.equals("lognormal")) { + return Double.NaN; + } else if (op.equals("binomial")) { + return Double.NaN; + } else if (op.equals("exponential")) { + return Double.NaN; + } else if (op.equals("chisq")) { + return Double.NaN; + } else if (op.equals("laplace")) { + return Double.NaN; + } else if (op.equals("cauchy")) { + return Double.NaN; + } else if (op.equals("rayleigh")) { + return Double.NaN; + } else if (op.equals("poisson")) { + return Double.NaN; + } else if (op.equals("bernoulli")) { + return Double.NaN; + } else if (op.equals("rate")) { + return Double.parseDouble(variables.get(r1.variable+"_" + GlobalConstants.RATE)); + } else if (op.equals("INT")) { + return ((int) left); + } else if (op.equals("<")) { + if (left < right) { + return 1.0; + } else if (left >= right) { + return 0.0; + } else { + return Double.NaN; + } + } else if (op.equals(">")) { + if (left > right) { + return 1.0; + } else if (left <= right) { + return 0.0; + } else { + return Double.NaN; + } + } else if (op.equals("<=")) { + if (left <= right) { + return 1.0; + } else if (left > right) { + return 0.0; + } else { + return Double.NaN; + } + } else if (op.equals(">=")) { + if (left >= right) { + return 1.0; + } else if (left < right) { + return 0.0; + } else { + return Double.NaN; + } + } else { + return Double.NaN; + } + } + return Double.NaN; + } + + private static final int WORD = 1; + + private static final int IMPLIES = 7; + + private static final int END_OF_STRING = 2; + + private static final int INFIN = 2147483647; + + public String getOp() + { + return op; + } + + public ExprTree getLeftChild() + { + return r1; + } + + public ExprTree getRightChild() + { + return r2; + } + + @Override + public ExprTree clone(){ + + ExprTree ET = new ExprTree(); // ET phone home. + + ET.op = op; + + ET.isit = isit; + + ET.lvalue = lvalue; + + ET.uvalue = uvalue; + + ET.variable = variable; + + ET.real = real; + + ET.logical = logical; + + ET.r1 = r1 != null ? r1.clone() : null; + + ET.r2 = r2 != null ? r2.clone() : null; + + ET.tokvalue = tokvalue; + + ET.position = position; + + ET.token = token; + + ET.newresult = newresult != null ? newresult.clone() : null; + + //private ArrayList booleanSignals, integerSignals, continuousSignals; + + ET.booleanSignals = (ArrayList) booleanSignals.clone(); + + ET.integerSignals = (ArrayList) integerSignals.clone(); + + ET.continuousSignals = continuousSignals; + + ET.lhpn = lhpn; + + ET.expression = expression; + + return ET; + } + + /* + * Performs the same operation as this.clone except it does not copy the parsing information. + */ + public ExprTree shallowclone(){ + + ExprTree ET = new ExprTree(); // ET phone home. + + ET.op = op; + + ET.isit = isit; + + ET.lvalue = lvalue; + + ET.uvalue = uvalue; + + ET.variable = variable; + + ET.real = real; + + ET.logical = logical; + + ET.r1 = r1 != null ? r1.shallowclone() : null; + + ET.r2 = r2 != null ? r2.shallowclone() : null; + + //private ArrayList booleanSignals, integerSignals, continuousSignals; + + ET.booleanSignals = (ArrayList) booleanSignals.clone(); + + ET.integerSignals = (ArrayList) integerSignals.clone(); + + ET.continuousSignals = continuousSignals; + + ET.lhpn = lhpn; + + ET.expression = expression; + + return ET; + } + + public ExprTree getExprTree() { + token = this.intexpr_gettok(expression); + this.intexpr_L(expression); + return this; + } + public void setIntegerSignals(Set signalSet) { + for (String s : signalSet) { + integerSignals.add(s); + } + } + + /** + * Evaluates an expression tree involving ranges. + * Note: if no continuous variables are present, both z and continuousValues can be null. + * If continuous variables are present, then at least one must be non-null. Finally, if + * z is non-null, then the values will be taken from z and continuousValues will not be consulted. + * @param variables + * The values of the variables. + * @param z + * The zone containing the continuous variables. + * @param continuousValues + * The continuous variables along with their values. + * @return + * The range of values for the expression tree. + */ + public IntervalPair evaluateExprBound(HashMap variables, Equivalence z, +// HashMap continuousValues){ + HashMap continuousValues){ + + + /* + * The code for this method was modified from atacs/src/lhpnrsg.c. + */ + +// void exprsn::eval(lhpnStateADT cur_state,int nevents){ +// char log_val; +// int tl1,tl2,tu1,tu2,i,j,k; +// int preciser = 1; +// + + int lBound, uBound; + + // If lBound and uBound are never set, then return "don't know". + lBound = -INFIN; + uBound = INFIN; + + IntervalPair r1Range,r2Range = null; + + if(!op.equals("")){ +// if (op!=""){ +// //printf("%s, eval left child\n",op.c_str()); +// r1->eval(cur_state,nevents); +// if ((r1->lvalue == -INFIN)||(r1->uvalue == INFIN)){ +// lvalue = -INFIN; +// uvalue = INFIN; +// return; +// } + r1Range = r1.evaluateExprBound(variables, z, continuousValues); + if ((r1Range.get_LowerBound() == -INFIN) || (r1Range.get_UpperBound() == INFIN)){ + + return new IntervalPair(-INFIN, INFIN); + } + +// if (r2){ +// //printf("eval right child\n"); +// r2->eval(cur_state,nevents); +// if ((r2->lvalue == -INFIN)||(r2->uvalue == INFIN)){ +// lvalue = -INFIN; +// uvalue = INFIN; +// return; +// } +// } + if(r2 != null){ + r2Range = r2.evaluateExprBound(variables, z, continuousValues); + if ((r2Range.get_LowerBound() == - INFIN) || (r1Range.get_UpperBound() == INFIN)){ + return new IntervalPair(-INFIN, INFIN); + } + } else { + r2Range = new IntervalPair(-INFIN, INFIN); + } + +// if (op=="||"){ +// // logical OR +// if (r1->logical){ +// tl1 = r1->lvalue; +// tu1 = r1->uvalue; +// } + + if( op.equals("||")){ + Boolean tl1, tu1, tl2, tu2; + // logical OR + if(r1.logical){ + tl1 = r1Range.get_LowerBound() != 0; // false if value is zero and true otherwise + tu1 = r1Range.get_UpperBound() != 0; // false if value is zero and true otherwise + } + + else{ // convert numeric r1 to boolean +// else{//convert numeric r1 to boolean +// if ((r1->lvalue == 0)&&(r1->uvalue == 0)){//false +// tl1 = tu1 = 0; +// } + + if((r1Range.get_LowerBound() == 0) && (r1Range.get_UpperBound() == 0)){ // false + tl1 = tu1 = false; + } + +// else if ((r1->lvalue < 0)&&(r1->uvalue < 0)|| +// (r1->lvalue > 0)&&(r1->uvalue > 0)){//true +// tl1 = tu1 = 1; +// } + else if (((r1Range.get_LowerBound() < 0) && (r1Range.get_UpperBound() < 0)) || + ((r1Range.get_LowerBound() > 0) && (r1Range.get_UpperBound() > 0))){ // true + tl1 = tu1 = true; + } + +// else{ +// tl1 = 0; +// tu1 = 1; +// } +// } + + else{ + tl1 = false; + tu1 = true; + } + } + +// if (r2->logical){ +// tl2 = r2->lvalue; +// tu2 = r2->uvalue; +// } + + if(r2.logical){ // Note : r2Range can only be set if r2 was non-null. + tl2 = r2Range.get_LowerBound() != 0; // False if value is zero and true otherwise. + tu2 = r2Range.get_UpperBound() != 0; // False if value is zero and true otherwise. + } + else{// convert numeric r2 to boolean +// else{//convert numeric r2 to boolean +// if ((r2->lvalue == 0)&&(r2->uvalue == 0)){//false +// tl2 = tu2 = 0; +// } + if((r2Range.get_LowerBound() == 0) && (r2Range.get_UpperBound() == 0)){// false + tl2 = tu2 = false; + } + +// else if ((r2->lvalue < 0)&&(r2->uvalue < 0)|| +// (r2->lvalue > 0)&&(r2->uvalue > 0)){//true +// tl2 = tu2 = 1; +// } + else if (((r2Range.get_LowerBound() < 0) && (r2Range.get_UpperBound() < 0)) || + ((r2Range.get_LowerBound() > 0) && (r2Range.get_UpperBound() > 0))){ // true + tl2 = tu2 = true; + } +// else{ +// tl2 = 0; +// tu2 = 1; +// } +// } + else{ + tl2 = false; + tu2 = true; + } + } +// lvalue = tl1 || tl2; +// uvalue = tu1 || tu2; + +// lBound = tl1 || lt2; +// uBound = tu1 || tu2; + + lBound = (tl1 || tl2) ? 1 : 0; // Poor man casting from boolean to int. + uBound = (tu1 || tu2) ? 1 : 0; + + } +// }else if(op=="&&"){ +// // logical AND + + else if (op.equals("&&")){ // logical AND + Boolean tl1, tu1, tl2, tu2; +// if (r1->logical){ +// tl1 = r1->lvalue; +// tu1 = r1->uvalue; +// } + if(r1.logical){ + tl1 = r1Range.get_LowerBound() != 0; // false if value is zero and true otherwise + tu1 = r1Range.get_UpperBound() != 0; // false if value is zero and true otherwise + } + +// else{//convert numeric r1 to boolean +// if ((r1->lvalue == 0)&&(r1->uvalue == 0)){//false +// tl1 = tu1 = 0; +// } + + else{ // convert number r1 to boolean + if((r1Range.get_LowerBound() == 0) && (r1Range.get_UpperBound() == 0)){ // false + tl1 = tu1 = false; + } + + +// else if ((r1->lvalue < 0)&&(r1->uvalue < 0)|| +// (r1->lvalue > 0)&&(r1->uvalue > 0)){//true +// tl1 = tu1 = 1; +// } + + else if (((r1Range.get_LowerBound() < 0) && (r1Range.get_UpperBound() < 0)) || + ((r1Range.get_LowerBound() > 0) && (r1Range.get_UpperBound() > 0))){ // true + tl1 = tu1 = true; + } + +// else{ +// tl1 = 0; +// tu1 = 1; +// } +// } + + else{ + tl1 = false; + tu1 = true; + } + } +// if (r2->logical){ +// tl2 = r2->lvalue; +// tu2 = r2->uvalue; +// } +// else{//convert numeric r2 to boolean + if(r2.logical){ // Note : r2Range can only be set if r2 was non-null. + tl2 = r2Range.get_LowerBound() != 0; // False if value is zero and true otherwise. + tu2 = r2Range.get_UpperBound() != 0; // False if value is zero and true otherwise. + } + else{// convert numeric r2 to boolean + +// if ((r2->lvalue == 0)&&(r2->uvalue == 0)){//false +// tl2 = tu2 = 0; +// } + + if((r2Range.get_LowerBound() == 0) && (r2Range.get_UpperBound() == 0)){// false + tl2 = tu2 = false; + } +// else if ((r2->lvalue < 0)&&(r2->uvalue < 0)|| +// (r2->lvalue > 0)&&(r2->uvalue > 0)){//true +// tl2 = tu2 = 1; +// } + + else if (((r2Range.get_LowerBound() < 0) && (r2Range.get_UpperBound() < 0)) || + ((r2Range.get_LowerBound() > 0) && (r2Range.get_UpperBound() > 0))){ // true + tl2 = tu2 = true; + } + +// else{ +// tl2 = 0; +// tu2 = 1; +// } +// } + else{ + tl2 = false; + tu2 = true; + } + } +// lvalue = tl1 && tl2; +// uvalue = tu1 && tu2; + + lBound = (tl1 && tl2) ? 1 : 0; // Poor man casting from boolean to int. + uBound = (tu1 && tu2) ? 1 : 0; // Or clever way; depends on how you look at it. +// #ifdef __LHPN_EVAL__ +// printf("and: [%d,%d](%c)&[%d,%d](%c) = [%d,%d]\n",r1->lvalue, +// r1->uvalue,r1->isit,r2->lvalue,r2->uvalue,r2->isit,lvalue,uvalue); +// #endif + + } +// }else if(op=="->"){ +// // implication operator + else if(op.equals("->")){ // Implication operator. + Boolean tl1, tu1, tl2, tu2; +// if (r1->logical){ +// tl1 = r1->lvalue; +// tu1 = r1->uvalue; +// } +// else{//convert numeric r1 to boolean +// if ((r1->lvalue == 0)&&(r1->uvalue == 0)){//false +// tl1 = tu1 = 0; +// } +// else if ((r1->lvalue < 0)&&(r1->uvalue < 0)|| +// (r1->lvalue > 0)&&(r1->uvalue > 0)){//true +// tl1 = tu1 = 1; +// } +// else{ +// tl1 = 0; +// tu1 = 1; +// } +// } + + BooleanPair lowerBounds = logicalConversion(r1, r1Range); + tl1 = lowerBounds.get_lower(); + tu1 = lowerBounds.get_upper(); +// if (r2->logical){ +// tl2 = r2->lvalue; +// tu2 = r2->uvalue; +// } +// else{//convert numeric r2 to boolean +// if ((r2->lvalue == 0)&&(r2->uvalue == 0)){//false +// tl2 = tu2 = 0; +// } +// else if ((r2->lvalue < 0)&&(r2->uvalue < 0)|| +// (r2->lvalue > 0)&&(r2->uvalue > 0)){//true +// tl2 = tu2 = 1; +// } +// else{ +// tl2 = 0; +// tu2 = 1; +// } +// } +// lvalue = tl1 || !tl2; +// uvalue = tu1 || !tu2; + BooleanPair upperBounds = logicalConversion(r2, r2Range); + tl2 = upperBounds.get_lower(); + tu2 = upperBounds.get_upper(); + + + lBound = (tl1 || !tl2) ? 1 : 0; // Poor man casting from boolean to int. + uBound = (tu1 || !tu2) ? 1 : 0; // Or clever way; depends on how you look at it. + } +// }else if(op=="!"){ +// // logical NOT + else if(op.equals("!")){ + Boolean tl1, tu1; + + BooleanPair bounds = logicalConversion(r1, r1Range); + tl1 = bounds.get_lower(); + tu1 = bounds.get_upper(); +// if (r1->logical){ +// tl1 = r1->lvalue; +// tu1 = r1->uvalue; +// } +// else{//convert numeric r1 to boolean +// if ((r1->lvalue == 0)&&(r1->uvalue == 0)){//false +// tl1 = tu1 = 0; +// } +// else if ((r1->lvalue < 0)&&(r1->uvalue < 0)|| +// (r1->lvalue > 0)&&(r1->uvalue > 0)){//true +// tl1 = tu1 = 1; +// } +// else{ +// tl1 = 0; +// tu1 = 1; +// } +// } +// if (tl1 == tu1){ +// lvalue = 1- tl1; +// uvalue = 1- tl1; +// } + if(tl1 == tu1){ + lBound = !tl1 ? 1 : 0; + uBound = !tl1 ? 1 : 0; + } + +// #ifdef __LHPN_EVAL__ +// printf("not: [%d,%d](%c) = [%d,%d]\n",r1->lvalue, +// r1->uvalue,r1->isit,lvalue,uvalue); +// #endif +// //printf("negation: ~[%d,%d] = [%d,%d]\n",r1->lvalue,r1->uvalue, +// // lvalue,uvalue); + + } +// }else if(op=="=="){ +// // "equality" operator + else if (op.equals("==")){ //"equality" operator. +// // true if same point value +// if ((r1->lvalue == r1->uvalue) && (r2->lvalue == r2->uvalue) && +// (r1->lvalue == r2->uvalue)) +// lvalue = uvalue = 1; + + // true if same point value. + if((r1Range.get_LowerBound() == r1Range.get_UpperBound()) && + (r2Range.get_LowerBound() == r2Range.get_UpperBound()) && + (r1Range.get_LowerBound() == r2Range.get_UpperBound())){ + lBound = uBound = 1; + } + +// // false if no overlap +// else if ((r1->lvalue > r2->uvalue)||(r2->lvalue > r1->uvalue)) +// lvalue = uvalue = 0; + + // false if no overlap + else if ((r1Range.get_LowerBound() > r2Range.get_UpperBound()) || + (r2Range.get_LowerBound() > r1Range.get_UpperBound())){ + lBound = uBound = 0; + } + +// // maybe if overlap +// else{ +// lvalue = 0; +// uvalue = 1; +// } + + // maybe if overlap + else{ + lBound = 0; + uBound = 1; + } + +// #ifdef __LHPN_EVAL__ +// printf("[%d,%d]==[%d,%d]=[%d,%d]\n",r1->lvalue,r1->uvalue ,r2->lvalue,r2->uvalue,lvalue,uvalue); +// #endif + } + else if(op.equals(">")){// "greater than" operator +// }else if(op==">"){ +// // "greater than" operator +// //true if lower1 > upper2 +// if (r1->lvalue > r2->uvalue) +// lvalue = uvalue = 1; + + // true if lower1 > upper2 + if( r1Range.get_LowerBound() > r2Range.get_UpperBound()){ + lBound = uBound = 1; + } + +// //false if lower2 >= upper1 +// else if (r2->lvalue >= r1->uvalue) +// lvalue = uvalue = 0; + + // false if lower 2 >= upper1 + else if (r2Range.get_LowerBound() >= r1Range.get_UpperBound()){ + lBound = uBound = 0; + } + +// // maybe if overlap +// else{ +// lvalue = 0; +// uvalue = 1; +// } + + // maybe, if overlap + else { + lBound = 0; + uBound = 1; + } + } +// }else if(op==">="){ +// // "greater than or equal" operator + else if (op.equals(">=")){ +// //true if lower1 >= upper2 +// if (r1->lvalue >= r2->uvalue) +// lvalue = uvalue = 1; + + // true if lower1 >= upper2 + if(r1Range.get_LowerBound() >= r2Range.get_UpperBound()){ + lBound = uBound = 1; + } + +// //false if lower2 > upper1 +// else if (r2->lvalue > r1->uvalue) +// lvalue = uvalue = 0; + + // false if lower2 > upper1 + else if (r2Range.get_LowerBound() > r1Range.get_UpperBound()){ + lBound = uBound = 0; + } + +// // maybe if overlap +// else{ +// lvalue = 0; +// uvalue = 1; +// } + + // maybe if overlap + else { + lBound = 0; + uBound = 1; + } + } +// }else if(op=="<"){ +// // "less than" operator + + else if (op.equals("<")){// "less than" operator. +// //true if lower2 > upper1 +// if (r2->lvalue > r1->uvalue) +// lvalue = uvalue = 1; + + // true if lower2 > upper1 + if(r2Range.get_LowerBound() > r1Range.get_UpperBound()){ + lBound = uBound = 1; + } +// //false if lower1 >= upper2 +// else if (r1->lvalue >= r2->uvalue) +// lvalue = uvalue = 0; + + // false if lower1 >= upper2 + else if (r1Range.get_LowerBound() >= r2Range.get_UpperBound()){ + lBound = uBound = 0; + } + +// // maybe if overlap +// else{ +// lvalue = 0; +// uvalue = 1; +// } + + // maybe if overlap + else{ + lBound = 0; + uBound = 1; + } + } +// }else if(op=="<="){ +// // "less than or equal" operator + + else if (op.equals("<=")){// "less than or equal" operator +// //true if lower2 >= upper1 +// if (r2->lvalue >= r1->uvalue) +// lvalue = uvalue = 1; + + // true if lower2 >= upper1 + if(r2Range.get_LowerBound() >= r1Range.get_UpperBound()){ + lBound = uBound = 1; + } + +// //false if lower1 > upper2 +// else if (r1->lvalue > r2->uvalue) +// lvalue = uvalue = 0; + + // false if lower1 > upper2 + else if (r1Range.get_LowerBound() > r2Range.get_UpperBound()){ + lBound = uBound =0; + } + +// // maybe if overlap +// else{ +// lvalue = 0; +// uvalue = 1; +// } + + // maybe if overlap + else { + lBound = 0; + uBound = 1; + } + +// #ifdef __LHPN_EVAL__ +// printf("[%d,%d]<=[%d,%d]=[%d,%d]\n",r1->lvalue,r1->uvalue ,r2->lvalue,r2->uvalue,lvalue,uvalue); +// #endif + } +// }else if(op=="[]"){//NEEDS WORK +// // bit extraction operator + + else if (op.equals("[]")){ // Apparently needs work. +// // Only extract if both are point values. +// if ((r1->lvalue == r1->uvalue)&&(r2->lvalue == r2->uvalue)){ +// lvalue = uvalue = (r1->lvalue >> r2->uvalue) & 1; +// } + if( (r1Range.get_LowerBound() == r1Range.get_UpperBound()) && + (r2Range.get_LowerBound() == r2Range.get_UpperBound())){ + lBound = uBound = + (r1Range.get_LowerBound() >> r2Range.get_UpperBound()) & 1; + } +// else { +// if (!preciser) +// { +// lvalue = 0; +// uvalue = 1; +// } +// else { +// uvalue = 0; +// lvalue = 1; +// for (i = r1->lvalue;i<=r1->uvalue;i++) +// for (j = r2->lvalue;j<=r2->uvalue;j++){ +// k = (i >> j) & 1; +// lvalue &= k; +// uvalue |= k; +// if (lvalue < uvalue) +// return; +// } +// } +// } + + else{ + // Not doing the !preciser part. + uBound = 0; + lBound = 1; + for (int i = r1Range.get_LowerBound(); i> j) & 1; + lBound &= k; + uBound |= k; + if(lBound < uBound){ + return new IntervalPair(lBound, uBound); + } + } + } + + } + + } +// }else if(op=="+"){ +// lvalue = r1->lvalue + r2->lvalue; +// uvalue = r1->uvalue + r2->uvalue; + + else if (op.equals("+")){ + lBound = r1Range.get_LowerBound() + r2Range.get_LowerBound(); + uBound = r1Range.get_UpperBound() + r2Range.get_UpperBound(); + } + +// }else if(op=="-"){ +// lvalue = r1->lvalue - r2->uvalue; +// uvalue = r1->uvalue - r2->lvalue; + + else if (op.equals("-")){ + lBound = r1Range.get_LowerBound() - r2Range.get_LowerBound(); + uBound = r1Range.get_UpperBound() - r2Range.get_UpperBound(); + } + +// }else if(op=="*"){ +// tl1 = r1->lvalue * r2->lvalue; +// tl2 = r1->uvalue * r2->uvalue; +// tu1 = r1->lvalue * r2->uvalue; +// tu2 = r1->uvalue * r2->lvalue; +// lvalue = min(min(min(tl1,tl2),tu1),tu2); +// uvalue = max(max(max(tl1,tl2),tu1),tu2); + + else if (op.equals("*")){ + int tl1, tl2, tu1, tu2; + tl1 = r1Range.get_LowerBound() * r2Range.get_LowerBound(); + tl2 = r1Range.get_UpperBound() * r2Range.get_UpperBound(); + tu1 = r1Range.get_LowerBound() * r2Range.get_UpperBound(); + tu2 = r1Range.get_UpperBound() * r2Range.get_LowerBound(); + lBound = Math.min(Math.min(Math.min(tl1, tl2), tu1), tu2); + uBound = Math.max(Math.max(Math.max(tl1, tl2), tu1), tu2); + } + +// }else if(op=="^"){ +// tl1 = pow((double)r1->lvalue,(double)r2->lvalue); +// tl2 = pow((double)r1->uvalue,(double)r2->uvalue); +// tu1 = pow((double)r1->lvalue,(double)r2->uvalue); +// tu2 = pow((double)r1->uvalue,(double)r2->lvalue); +// lvalue = min(min(min(tl1,tl2),tu1),tu2); +// uvalue = max(max(max(tl1,tl2),tu1),tu2); + + else if (op.equals("^")){ + double tl1, tl2, tu1, tu2; + tl1 = Math.pow(r1Range.get_LowerBound(), r2Range.get_LowerBound()); + tl2 = Math.pow(r1Range.get_UpperBound(), r2Range.get_UpperBound()); + tu1 = Math.pow(r1Range.get_LowerBound(), r2Range.get_UpperBound()); + tu2 = Math.pow(r1Range.get_UpperBound(), r2Range.get_LowerBound()); + lBound = (int) Math.min(Math.min(Math.min(tl1, tl2), tu1), tu2); + uBound = (int) Math.max(Math.max(Math.max(tl1, tl2), tu1), tu2); + } + +// }else if(op=="u"){ +// lvalue = r1->lvalue; +// uvalue = r2->uvalue; + + else if (op.equals("uniform")){ + lBound = r1Range.get_LowerBound(); + uBound = r2Range.get_UpperBound(); + } + else if (op.equals("rate")){ + LPNContinuousPair lcPair = new LPNContinuousPair(r1.lhpn.getLpnIndex(), + lhpn.getContVarIndex(r1.variable)); + lBound = z.getCurrentRate(lcPair); + uBound = z.getCurrentRate(lcPair); + } +// }else if(op=="/"){ +// //ropughly integer division. +// //DON"T KNOW WHAT FLOATING POINT PART IS!!!!! +// tl1 = floor(r1->lvalue / r2->lvalue); +// tl2 = floor(r1->uvalue / r2->uvalue); +// tu1 = floor(r1->lvalue / r2->uvalue); +// tu2 = floor(r1->uvalue / r2->lvalue); +// lvalue = min(min(min(tl1,tl2),tu1),tu2); +// tl1 = ceil(r1->lvalue / r2->lvalue); +// tl2 = ceil(r1->uvalue / r2->uvalue); +// tu1 = ceil(r1->lvalue / r2->uvalue); +// tu2 = ceil(r1->uvalue / r2->lvalue); +// uvalue = max(max(max(tl1,tl2),tu1),tu2); + + else if (op.equals("/")){ // roughly integer division. + // STILL DON'T KNOW WHAT FLOATING POINT PART IS !!!! :) !!!! + double tl1, tl2, tu1, tu2; + tl1 = Math.floor(((double)r1Range.get_LowerBound()) / r2Range.get_LowerBound()); + tl2 = Math.floor(((double)r1Range.get_UpperBound()) / r2Range.get_UpperBound()); + tu1 = Math.floor(((double)r1Range.get_LowerBound()) / r2Range.get_UpperBound()); + tu2 = Math.floor(((double)r1Range.get_UpperBound()) / r2Range.get_LowerBound()); + lBound = (int) Math.min(Math.min(Math.min(tl1, tl2), tu1), tu2); + tl1 = Math.ceil(((double)r1Range.get_LowerBound()) / r2Range.get_LowerBound()); + tl2 = Math.ceil(((double)r1Range.get_UpperBound()) / r2Range.get_UpperBound()); + tu1 = Math.ceil(((double)r1Range.get_LowerBound()) / r2Range.get_UpperBound()); + tu2 = Math.ceil(((double)r1Range.get_UpperBound()) / r2Range.get_LowerBound()); + uBound = (int) Math.max(Math.max(Math.max(tl1, tl2), tu1), tu2); + } + +// }else if(op=="%"){//NEEDS WORK + + else if (op.equals("%")){// STILL NEEDS WORK. + +// if (!preciser){ +// // Only calculate if both are point values. +// if ((r1->lvalue == r1->uvalue)&&(r2->lvalue == r2->uvalue)){ +// lvalue = uvalue = r1->lvalue % r2->uvalue; +// } +// else{ +// lvalue = min(0,max(-(max(abs(r2->lvalue),abs(r2->lvalue))-1),r1->lvalue)); +// uvalue = max(0,min(max(abs(r2->lvalue),abs(r2->uvalue))-1,r1->uvalue)); +// } +// } +// else{ +// uvalue = -INFIN; +// lvalue = INFIN; +// for (i = r1->lvalue;i<=r1->uvalue;i++) +// for (j = r2->lvalue;j<=r2->uvalue;j++){ +// k = i%j; +// if (k < lvalue) +// lvalue = k; +// if (k > uvalue) +// uvalue = k; +// } +// } + + // Not doing the !precier part. + + lBound = -INFIN; + uBound = INFIN; + for (int i = r1Range.get_LowerBound(); i <= r1Range.get_UpperBound(); i++){ + for ( int j = r2Range.get_LowerBound(); j <= r2Range.get_UpperBound(); j++){ + int k = i%j; + if(k < lBound){ + lBound = k; + } + if( k > uBound){ + uBound = k; + } + } + } + + } + +// }else if(op=="U-"){ +// lvalue = -(r1->uvalue); +// uvalue = -(r1->lvalue); + + else if (op.equals("U-")){ + lBound = -1 * r1Range.get_UpperBound(); + uBound = -1 * (r1Range.get_LowerBound()); + } + +// }else if(op=="INT"){ +// lvalue = r1->lvalue; +// uvalue = r1->uvalue; + + else if (op.equals("INT")){ + lBound = r1Range.get_LowerBound(); + uBound = r1Range.get_UpperBound(); + } + +// }else if(op=="BOOL"){ +// if ((r1->lvalue == 0)&& (r1->uvalue == 0)) +// lvalue = uvalue = 0; +// else if (((r1->lvalue > 0) && (r1->uvalue > 0))|| +// ((r1->lvalue < 0) && (r1->uvalue < 0))) +// lvalue = uvalue = 1; +// else { +// lvalue = 0; +// uvalue = 1; +// } + + else if(op.equals("BOOL")){ + if( (r1Range.get_LowerBound() == 0) && (r1Range.get_UpperBound() == 0)){ + lBound = uBound =0; + } + else if ((r1Range.get_LowerBound() > 0) && (r1Range.get_UpperBound() > 0) || + (r1Range.get_LowerBound() < 0) && (r1Range.get_UpperBound() < 0)){ + lBound = uBound =1 ; + } + else{ + lBound = 0; + uBound = 1; + } + } + +// }else if(op=="&"){ + + else if(op.equals("&")){ +// if ((r1->lvalue!=r1->uvalue)||(r2->lvalue!=r2->uvalue)) { + + if((r1Range.get_LowerBound() != r1Range.get_UpperBound()) || + (r2Range.get_LowerBound() != r2Range.get_UpperBound())){ + +// if (!preciser){ +// lvalue = min(r1->lvalue+r2->lvalue,0); +// uvalue = max((r1->uvalue),(r2->uvalue)); +// } +// else{ +// uvalue = -INFIN; +// lvalue = INFIN; +// for (i = r1->lvalue;i<=r1->uvalue;i++) +// for (j = r2->lvalue;j<=r2->uvalue;j++){ +// k = i&j; +// if (k < lvalue) +// lvalue = k; +// if (k > uvalue) +// uvalue = k; +// } +// } +// } + + // Not doing the !preciser part. + uBound = -INFIN; + lBound = INFIN; + for( int i=r1Range.get_LowerBound(); i<=r1Range.get_UpperBound(); i++){ + for(int j=r2Range.get_LowerBound(); j<=r2Range.get_UpperBound(); j++){ + int k = i&j; + if (k < lBound){ + lBound =k; + } + if( k > uBound){ + uBound = k; + } + } + } + + + } +// else { +// lvalue = (r1->lvalue & r2->lvalue); +// uvalue = (r1->lvalue & r2->lvalue); +// } + + else { + lBound = (r1Range.get_LowerBound() & r2Range.get_LowerBound()); + uBound = (r1Range.get_LowerBound() & r2Range.get_LowerBound()); + } +// #ifdef __LHPN_EVAL__ +// printf("BITWISE AND: [%d,%d](%c)&[%d,%d](%c) = [%d,%d]\n",r1->lvalue, +// r1->uvalue,r1->isit,r2->lvalue,r2->uvalue,r2->isit,lvalue,uvalue); +// #endif + } + +// }else if(op=="|"){ + else if (op.equals("|")){ +// if ((r1->lvalue!=r1->uvalue)||(r2->lvalue!=r2->uvalue)) { +// lvalue = min(r1->lvalue,r2->lvalue); +// uvalue = max(r1->uvalue + r2->uvalue,-1); +// } else { +// lvalue = (r1->lvalue | r2->lvalue); +// uvalue = (r1->lvalue | r2->lvalue); +// } + + if((r1Range.get_LowerBound() != r1Range.get_UpperBound()) || + (r2Range.get_LowerBound() != r2Range.get_UpperBound())){ + + lBound = Math.min(r1Range.get_LowerBound(), r2Range.get_LowerBound()); + uBound = Math.max(r1Range.get_UpperBound() + r2Range.get_UpperBound(), -1); + } + else { + lBound = (r1Range.get_LowerBound() | r2Range.get_LowerBound()); + uBound = (r1Range.get_LowerBound() | r2Range.get_LowerBound()); + } + + } +// }else if(op=="m"){ +// lvalue = min(r1->lvalue,r2->lvalue); +// uvalue = min(r1->uvalue,r2->uvalue); + else if(op.equals("m")){ + lBound = Math.min(r1Range.get_LowerBound(), r2Range.get_LowerBound()); + uBound = Math.min(r1Range.get_UpperBound(), r2Range.get_UpperBound()); + } + +// }else if(op=="M"){ +// lvalue = max(r1->lvalue,r2->lvalue); +// uvalue = max(r1->uvalue,r2->uvalue); + else if (op.equals("M")){ + lBound = Math.max(r1Range.get_LowerBound(), r2Range.get_LowerBound()); + uBound = Math.max(r1Range.get_UpperBound(), r2Range.get_UpperBound()); + + } + +// }else if(op=="i"){ +// tl1 = r1->lvalue / r2->lvalue; +// tl2 = r1->uvalue / r2->uvalue; +// tu1 = r1->lvalue / r2->uvalue; +// tu2 = r1->uvalue / r2->lvalue; +// lvalue = min(min(min(tl1,tl2),tu1),tu2); +// uvalue = max(max(max(tl1,tl2),tu1),tu2); + + else if (op.equals("i")){ + + int tl1, tl2, tu1, tu2; + tl1 = r1Range.get_LowerBound() / r2Range.get_LowerBound(); + tl2 = r1Range.get_UpperBound() / r2Range.get_UpperBound(); + tu1 = r1Range.get_LowerBound() / r2Range.get_UpperBound(); + tu2 = r1Range.get_UpperBound() / r2Range.get_LowerBound(); + lBound = Math.min(Math.min(Math.min(tl1, tl2), tu1), tu2); + uBound = Math.max(Math.max(Math.max(tl1, tl2), tu1), tu2); + } + +// }else if(op=="X"){ +// lvalue = min(min(r1->lvalue-r2->uvalue,r2->lvalue-r1->uvalue),0); +// uvalue = max(max(r1->uvalue + r2->uvalue,-(r1->lvalue + r2->lvalue)),-1); + else if(op.equals("X")){ + lBound = Math.min(Math.min(r1Range.get_LowerBound()-r2Range.get_UpperBound(), + r2Range.get_LowerBound()-r1Range.get_UpperBound()), 0); + uBound = Math.max(Math.max(r1Range.get_UpperBound()+r2Range.get_UpperBound(), + r2Range.get_LowerBound()+r1Range.get_LowerBound()), -1); + } +//// }else if(op=="floor"){ +//// lvalue = floor(r1->lvalue); +//// uvalue = floor(r1->uvalue); +//// }else if(op=="round"){ +//// lvalue = round(r1->lvalue); +//// uvalue = round(r1->uvalue); +//// }else if(op=="ceil"){ +//// lvalue = ceil(r1->lvalue); +//// uvalue = ceil(r1->uvalue); + + +// }else if(op=="~"){ +// //bitwise negation operator (1's complement) +// lvalue = -((r1->uvalue)+1); +// uvalue = -((r1->lvalue)+1); +// } + + else if (op.equals("~")){ + // bitwise negation operator (1's complement) + lBound = -1*(r1Range.get_LowerBound()); + uBound = -1*(r1Range.get_UpperBound()); + + } +// }else if(isit == 'd'){ +// for (i = 1;iz->size;i++){ +// if (cur_state->z->curClocks[i].enabled == index){ +// lvalue = cur_state->r->bound[cur_state->z->curClocks[i].enabled-nevents].lower; +// uvalue = cur_state->r->bound[cur_state->z->curClocks[i].enabled-nevents].upper; +// #ifdef __LHPN_EVAL__ +// printf("lv=%d,uv=%d,index=%d,i=%d\n",lvalue, uvalue,index,i); +// #endif +// break; +// } +// } + + // Not present in the current implementation. These are 'i'. +// else if (isit == 'd'){ +// //Check what this is before doing it. +// } + +// }else{ + } + else{ +// if ((isit == 'i')||(isit == 'c')){ + + if(isit == 'i'){ + +// for (i = 1;iz->size;i++){ +// if (cur_state->z->curClocks[i].enabled == index){ +// if (i>=cur_state->z->dbmEnd){ +// lvalue = -1*(cur_state->z->matrix[0][i]); +// uvalue = cur_state->z->matrix[i][0]; +// } + + + // Get the value of the variable from the passed HashMap and convert it as appropriate. + String sV = variables.get(variable); // sV for "string value" + + if(sV != null){ + + int tmp = Integer.parseInt(sV); + + // Currently the platu.state does not support integer ranges. + lBound = uBound = tmp; + } + else{ + lBound = -INFIN; + uBound = INFIN; + } + + +// else{// uses lower rate bound for both???? +// lvalue = -1*(cur_state->z->matrix[0][i])* +// cur_state->r->bound[cur_state->z->curClocks[i].enabled-nevents].current; +// uvalue = cur_state->z->matrix[i][0]* +// cur_state->r->bound[cur_state->z->curClocks[i].enabled-nevents].current; +// } +// #ifdef __LHPN_EVAL__ +// printf("lv=%d,uv=%d,index=%d,i=%d\n",lvalue, uvalue,index,i); +// #endif +// break; +// } +// } + } + + else if(isit == 'c'){ +// if(z != null){ +// return z.getContinuousBounds(variable, lhpn); +// } +// else{ +// return continuousValues.get(new LPNContinuousPair(lhpn.getLpnIndex(), +// lhpn.getContVarIndex(variable))); +// } + LPNContinuousPair lcPair = new LPNContinuousPair(lhpn.getLpnIndex(), + lhpn.getContVarIndex(variable)); + + IntervalPair result = null; + if(continuousValues != null){ + result = continuousValues.get(new LPNContAndRate(lcPair)); + } + if(result != null){ + return result; + } + return z.getContinuousBounds(variable, lhpn); + + } + + else if (isit == 'b'){ +// }else if (isit == 'b'){ +// log_val = cur_state->m->state[index]; +// if (log_val == '1'){ +// lvalue = 1; +// uvalue = 1; +// } else if (log_val == 'X'){ +// lvalue = 0; +// uvalue = 1; +// } else if (log_val == '0'){ +// lvalue = 0; +// uvalue = 0; +// } +// #ifdef __LHPN_EVAL__ +// printf("successful lookup of boolean %d,%c[%d,%d]\n",index, +// cur_state->m->state[index],lvalue,uvalue); +// #endif + + // Get the value of the variable from the passed HashMap and convert it as appropriate. + String sV = variables.get(variable); // sV for "string value" + + if(sV != null){ + int tmp = (sV.toLowerCase().equals("true") || sV.equals("1")) ? 1 : 0; + + // Currently the platu.state does not support boolean ranges. + lBound = uBound = tmp; + } + else{ + lBound = 0; + uBound = 1; + } + + } + + else if(isit == 'n'){ + +// }else if ((isit == 'n')||(isit == 't')){ +// // values already stored, no need to evaluate! +// } +// } + + lBound = uBound = (int) lvalue; + + +// if (uvalue == lvalue) { +// return uvalue; +// } else { +// return ((uvalue - lvalue) * new java.util.Random().nextDouble()) +// + lvalue; +// } + + } + + else if ((isit == 't')){ + + // Should be fine to use the lvalue and uvalue. + + lBound = (int) lvalue; + uBound = (int) uvalue; + + +// // Get the value of the variable from the passed HashMap and convert it as appropriate. +// String sV = variables.get(variable); // sV for "string value" +// +// if(sV != null){ +// lBound = uBound = 1; +// } +// else{ +// lBound = 0; +// uBound = 1; +// } + } + +// }; + } + + + // TODO : need to return an appropriate value when the operation is "". + return new IntervalPair(lBound, uBound); + } + + /** + * Converts an integer range for an expression tree representing a logical into + * a boolean pair. + * @param expr + * An expression tree. + * @param range + * The integer range. + * @return + * The range converted to a boolean pair if expr.logical is true and range is non-null. + */ + private BooleanPair logicalConversion(ExprTree expr, IntervalPair range){ + Boolean lower, upper; + + if( range != null && expr.logical){ // Note : range can only be set if range is non-null. + lower = range.get_LowerBound() != 0; // False if value is zero and true otherwise. + upper = range.get_UpperBound() != 0; // False if value is zero and true otherwise. + } + else{ + + if (range!=null) { + if((range.get_LowerBound() == 0) && (range.get_UpperBound() == 0)){// false + lower = upper = false; + } + else if (((range.get_LowerBound() < 0) && (range.get_UpperBound() < 0)) || + ((range.get_LowerBound() > 0) && (range.get_UpperBound() > 0))){ // true + lower = upper = true; + } + + else{ + lower = false; + upper = true; + } + } else { + lower = false; + upper = true; + } + } + return new BooleanPair(lower, upper); + } + +//------------------------------- Inner Class ------------------------------------- + private class BooleanPair { + + private Boolean _lower; + private Boolean _upper; + + public BooleanPair(Boolean lower, Boolean upper) { + super(); + this._lower = lower; + this._upper = upper; + } + + public Boolean get_lower() { + return _lower; + } + +// public void set_lower(Boolean lower) { +// this._lower = lower; +// } + + public Boolean get_upper() { + return _upper; + } + +// public void set_upper(Boolean upper) { +// this._upper = upper; +// } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((_lower == null) ? 0 : _lower.hashCode()); + result = prime * result + ((_upper == null) ? 0 : _upper.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof BooleanPair)) + return false; + BooleanPair other = (BooleanPair) obj; + if (_lower == null) { + if (other._lower != null) + return false; + } else if (!_lower.equals(other._lower)) + return false; + if (_upper == null) { + if (other._upper != null) + return false; + } else if (!_upper.equals(other._upper)) + return false; + return true; + } + + @Override + public String toString() { + return "BooleanPair [lower=" + _lower + ", upper=" + _upper + "]"; + } + + } +} \ No newline at end of file diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/JavaCharStream.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/JavaCharStream.java new file mode 100644 index 000000000..99c64e5ea --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/JavaCharStream.java @@ -0,0 +1,626 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 5.0 */ +/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +package edu.utah.ece.async.lema.verification.lpn; + +/** + * An implementation of interface CharStream, where the stream is assumed to + * contain only ASCII characters (with java-like unicode escape processing). + + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public +class JavaCharStream +{ + /** Whether parser is static. */ + public static final boolean staticFlag = false; + + static final int hexval(char c) throws java.io.IOException { + switch(c) + { + case '0' : + return 0; + case '1' : + return 1; + case '2' : + return 2; + case '3' : + return 3; + case '4' : + return 4; + case '5' : + return 5; + case '6' : + return 6; + case '7' : + return 7; + case '8' : + return 8; + case '9' : + return 9; + + case 'a' : + case 'A' : + return 10; + case 'b' : + case 'B' : + return 11; + case 'c' : + case 'C' : + return 12; + case 'd' : + case 'D' : + return 13; + case 'e' : + case 'E' : + return 14; + case 'f' : + case 'F' : + return 15; + } + + throw new java.io.IOException(); // Should never come here + } + +/** Position in buffer. */ + public int bufpos = -1; + int bufsize; + int available; + int tokenBegin; + protected int bufline[]; + protected int bufcolumn[]; + + protected int column = 0; + protected int line = 1; + + protected boolean prevCharIsCR = false; + protected boolean prevCharIsLF = false; + + protected java.io.Reader inputStream; + + protected char[] nextCharBuf; + protected char[] buffer; + protected int maxNextCharInd = 0; + protected int nextCharInd = -1; + protected int inBuf = 0; + protected int tabSize = 8; + + protected void setTabSize(int i) { tabSize = i; } + protected int getTabSize() { return tabSize; } + + protected void ExpandBuff(boolean wrapAround) + { + char[] newbuffer = new char[bufsize + 2048]; + int newbufline[] = new int[bufsize + 2048]; + int newbufcolumn[] = new int[bufsize + 2048]; + + try + { + if (wrapAround) + { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); + bufcolumn = newbufcolumn; + + bufpos += (bufsize - tokenBegin); + } + else + { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + bufcolumn = newbufcolumn; + + bufpos -= tokenBegin; + } + } + catch (Throwable t) + { + throw new Error(t.getMessage()); + } + + available = (bufsize += 2048); + tokenBegin = 0; + } + + protected void FillBuff() throws java.io.IOException + { + int i; + if (maxNextCharInd == 4096) + maxNextCharInd = nextCharInd = 0; + + try { + if ((i = inputStream.read(nextCharBuf, maxNextCharInd, + 4096 - maxNextCharInd)) == -1) + { + inputStream.close(); + throw new java.io.IOException(); + } + maxNextCharInd += i; + return; + } + catch(java.io.IOException e) { + if (bufpos != 0) + { + --bufpos; + backup(0); + } + else + { + bufline[bufpos] = line; + bufcolumn[bufpos] = column; + } + throw e; + } + } + + protected char ReadByte() throws java.io.IOException + { + if (++nextCharInd >= maxNextCharInd) + FillBuff(); + + return nextCharBuf[nextCharInd]; + } + +/** @return starting character for token. */ + public char BeginToken() throws java.io.IOException + { + if (inBuf > 0) + { + --inBuf; + + if (++bufpos == bufsize) + bufpos = 0; + + tokenBegin = bufpos; + return buffer[bufpos]; + } + + tokenBegin = 0; + bufpos = -1; + + return readChar(); + } + + protected void AdjustBuffSize() + { + if (available == bufsize) + { + if (tokenBegin > 2048) + { + bufpos = 0; + available = tokenBegin; + } + else + ExpandBuff(false); + } + else if (available > tokenBegin) + available = bufsize; + else if ((tokenBegin - available) < 2048) + ExpandBuff(true); + else + available = tokenBegin; + } + + protected void UpdateLineColumn(char c) + { + column++; + + if (prevCharIsLF) + { + prevCharIsLF = false; + line += (column = 1); + } + else if (prevCharIsCR) + { + prevCharIsCR = false; + if (c == '\n') + { + prevCharIsLF = true; + } + else + line += (column = 1); + } + + switch (c) + { + case '\r' : + prevCharIsCR = true; + break; + case '\n' : + prevCharIsLF = true; + break; + case '\t' : + column--; + column += (tabSize - (column % tabSize)); + break; + default : + break; + } + + bufline[bufpos] = line; + bufcolumn[bufpos] = column; + } + +/** Read a character. */ + public char readChar() throws java.io.IOException + { + if (inBuf > 0) + { + --inBuf; + + if (++bufpos == bufsize) + bufpos = 0; + + return buffer[bufpos]; + } + + char c; + + if (++bufpos == available) + AdjustBuffSize(); + + if ((buffer[bufpos] = c = ReadByte()) == '\\') + { + UpdateLineColumn(c); + + int backSlashCnt = 1; + + for (;;) // Read all the backslashes + { + if (++bufpos == available) + AdjustBuffSize(); + + try + { + if ((buffer[bufpos] = c = ReadByte()) != '\\') + { + UpdateLineColumn(c); + // found a non-backslash char. + if ((c == 'u') && ((backSlashCnt & 1) == 1)) + { + if (--bufpos < 0) + bufpos = bufsize - 1; + + break; + } + + backup(backSlashCnt); + return '\\'; + } + } + catch(java.io.IOException e) + { + // We are returning one backslash so we should only backup (count-1) + if (backSlashCnt > 1) + backup(backSlashCnt-1); + + return '\\'; + } + + UpdateLineColumn(c); + backSlashCnt++; + } + + // Here, we have seen an odd number of backslash's followed by a 'u' + try + { + while ((c = ReadByte()) == 'u') + ++column; + + buffer[bufpos] = c = (char)(hexval(c) << 12 | + hexval(ReadByte()) << 8 | + hexval(ReadByte()) << 4 | + hexval(ReadByte())); + + column += 4; + } + catch(java.io.IOException e) + { + throw new Error("Invalid escape character at line " + line + + " column " + column + "."); + } + + if (backSlashCnt == 1) + return c; + backup(backSlashCnt - 1); + return '\\'; + } + UpdateLineColumn(c); + return c; + } + + @Deprecated + /** + * @deprecated + * @see #getEndColumn + */ + public int getColumn() { + return bufcolumn[bufpos]; + } + + @Deprecated + /** + * @deprecated + * @see #getEndLine + */ + public int getLine() { + return bufline[bufpos]; + } + +/** Get end column. */ + public int getEndColumn() { + return bufcolumn[bufpos]; + } + +/** Get end line. */ + public int getEndLine() { + return bufline[bufpos]; + } + +/** @return column of token start */ + public int getBeginColumn() { + return bufcolumn[tokenBegin]; + } + +/** @return line number of token start */ + public int getBeginLine() { + return bufline[tokenBegin]; + } + +/** Retreat. */ + public void backup(int amount) { + + inBuf += amount; + if ((bufpos -= amount) < 0) + bufpos += bufsize; + } + +/** Constructor. */ + public JavaCharStream(java.io.Reader dstream, + int startline, int startcolumn, int buffersize) + { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + nextCharBuf = new char[4096]; + } + +/** Constructor. */ + public JavaCharStream(java.io.Reader dstream, + int startline, int startcolumn) + { + this(dstream, startline, startcolumn, 4096); + } + +/** Constructor. */ + public JavaCharStream(java.io.Reader dstream) + { + this(dstream, 1, 1, 4096); + } +/** Reinitialise. */ + public void ReInit(java.io.Reader dstream, + int startline, int startcolumn, int buffersize) + { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + if (buffer == null || buffersize != buffer.length) + { + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + nextCharBuf = new char[4096]; + } + prevCharIsLF = prevCharIsCR = false; + tokenBegin = inBuf = maxNextCharInd = 0; + nextCharInd = bufpos = -1; + } + +/** Reinitialise. */ + public void ReInit(java.io.Reader dstream, + int startline, int startcolumn) + { + ReInit(dstream, startline, startcolumn, 4096); + } + +/** Reinitialise. */ + public void ReInit(java.io.Reader dstream) + { + ReInit(dstream, 1, 1, 4096); + } +/** Constructor. */ + public JavaCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException + { + this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + +/** Constructor. */ +public JavaCharStream(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) + { + this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096); + } + +/** Constructor. */ + public JavaCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException + { + this(dstream, encoding, startline, startcolumn, 4096); + } + +/** Constructor. */ + public JavaCharStream(java.io.InputStream dstream, int startline, + int startcolumn) + { + this(dstream, startline, startcolumn, 4096); + } + +/** Constructor. */ + public JavaCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException + { + this(dstream, encoding, 1, 1, 4096); + } + +/** Constructor. */ + public JavaCharStream(java.io.InputStream dstream) + { + this(dstream, 1, 1, 4096); + } + +/** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException + { + ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + +/** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) + { + ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } +/** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException + { + ReInit(dstream, encoding, startline, startcolumn, 4096); + } +/** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn) + { + ReInit(dstream, startline, startcolumn, 4096); + } +/** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException + { + ReInit(dstream, encoding, 1, 1, 4096); + } + +/** Reinitialise. */ + public void ReInit(java.io.InputStream dstream) + { + ReInit(dstream, 1, 1, 4096); + } + + /** @return token image as String */ + public String GetImage() + { + if (bufpos >= tokenBegin) + return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); + return new String(buffer, tokenBegin, bufsize - tokenBegin) + + new String(buffer, 0, bufpos + 1); + } + + /** @return suffix */ + public char[] GetSuffix(int len) + { + char[] ret = new char[len]; + + if ((bufpos + 1) >= len) + System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); + else + { + System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, + len - bufpos - 1); + System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); + } + + return ret; + } + + /** Set buffers back to null when finished. */ + public void Done() + { + nextCharBuf = null; + buffer = null; + bufline = null; + bufcolumn = null; + } + + /** + * Method to adjust line and column numbers for the start of a token. + */ + public void adjustBeginLineColumn(int newLine, int newCol) + { + int start = tokenBegin; + int len; + + if (bufpos >= tokenBegin) + { + len = bufpos - tokenBegin + inBuf + 1; + } + else + { + len = bufsize - tokenBegin + bufpos + 1 + inBuf; + } + + int i = 0, j = 0, k = 0; + int nextColDiff = 0, columnDiff = 0; + + while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) + { + bufline[j] = newLine; + nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; + bufcolumn[j] = newCol + columnDiff; + columnDiff = nextColDiff; + i++; + } + + if (i < len) + { + bufline[j] = newLine++; + bufcolumn[j] = newCol + columnDiff; + + while (i++ < len) + { + if (bufline[j = start % bufsize] != bufline[++start % bufsize]) + bufline[j] = newLine++; + else + bufline[j] = newLine; + } + } + + line = bufline[j]; + column = bufcolumn[j]; + } + +} +/* JavaCC - OriginalChecksum=d8bc55bac4472bc0df907ee2abfc3dd4 (do not edit this line) */ diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LPN.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LPN.java new file mode 100644 index 000000000..7b6da3ac6 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LPN.java @@ -0,0 +1,3209 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn; + + +import java.io.*; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.xml.stream.XMLStreamException; + +import org.sbml.jsbml.KineticLaw; +import org.sbml.jsbml.ListOf; +import org.sbml.jsbml.LocalParameter; +import org.sbml.jsbml.Reaction; +import org.sbml.jsbml.SBMLDocument; + +import edu.utah.ece.async.ibiosim.dataModels.biomodel.network.AbstractionEngine; +import edu.utah.ece.async.ibiosim.dataModels.biomodel.network.GeneticNetwork; +import edu.utah.ece.async.ibiosim.dataModels.biomodel.network.Promoter; +import edu.utah.ece.async.ibiosim.dataModels.biomodel.network.SpeciesInterface; +import edu.utah.ece.async.ibiosim.dataModels.biomodel.parser.BioModel; +import edu.utah.ece.async.ibiosim.dataModels.biomodel.parser.GCMParser; +import edu.utah.ece.async.ibiosim.dataModels.biomodel.util.SBMLutilities; +import edu.utah.ece.async.ibiosim.dataModels.util.GlobalConstants; +import edu.utah.ece.async.ibiosim.dataModels.util.Message; +import edu.utah.ece.async.ibiosim.dataModels.util.MutableString; +import edu.utah.ece.async.ibiosim.dataModels.util.exceptions.BioSimException; +import edu.utah.ece.async.lema.verification.platu.platuLpn.DualHashMap; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.InequalityVariable; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class LPN extends Observable { + + protected String separator; + + protected HashMap transitions; + + protected HashMap places; + + //protected HashMap placesIndices; + + protected HashMap booleans; + + protected HashMap continuous; + + protected HashMap integers; + + protected ArrayList variables; + + protected ArrayList properties; + + protected String label; + + protected int tranIndex; + + protected int lpnIndex; + + protected final Message message = new Message(); + + /* + * Cached value of the map that associates a variable name with its + * index. This field is initialized when a call to getVarIndexMap + * is made. + */ + protected DualHashMap _varIndexMap; + + /* + * Cached value of the map that associates a continuous variable with + * its index. This field is initialized when a call to getContinuousIndexMap + * is made. + */ + DualHashMap _continuousIndexMap; + + /* + * Cached value of the array of all the places in this LPN. This field is + * initialized when a call to getPlaceList is made. + */ + protected String[] placeList; + + /* + * Cached value of all the transition in this LPN. This field is + * initialized when a call to getAllTransitions is made. + */ + protected Transition[] allTransitions; + + /* + * The i-th array in this list stores THIS Lpn's variable indices of the shared variables + * between this LPN and another LPN whose lpnIndex is i. + */ + protected List thisIndexList; + + /* + * The i-th array in this list stores THE i-th Lpn's variable indices of the + * shared variables between this LPN and the i-th LPN. + */ + protected List otherIndexList; + + /* + * The local state graph that corresponds to this LPN. + */ + protected StateGraph stateGraph; + + protected HashMap implicitPlaceMap; + + private static int implicitPlaceCount=0; + + public LPN() { + separator = GlobalConstants.separator; + transitions = new HashMap(); + places = new HashMap(); + implicitPlaceMap = new HashMap(); + booleans = new HashMap(); + continuous = new HashMap(); + integers = new HashMap(); + variables = new ArrayList(); + properties = new ArrayList(); + lpnIndex = 0; + tranIndex = 0; + thisIndexList = new ArrayList(); + otherIndexList = new ArrayList(); + } + + public static LPN convertToLHPN(ArrayList specs, ArrayList conLevel, MutableString lpnProperty, + BioModel bioModel) throws XMLStreamException, IOException { + GCMParser parser = new GCMParser(bioModel); + SBMLDocument sbml = bioModel.flattenModel(true); + if (sbml == null) return null; + GeneticNetwork network = parser.buildNetwork(sbml); + if (network == null) return null; + network.markAbstractable(); + AbstractionEngine abs = network.createAbstractionEngine(); + ArrayList biochemical = bioModel.getBiochemicalSpecies(); + LPN LHPN = new LPN(); + for (int i = 0; i < specs.size(); i++) { + if (sbml.getModel().getSpecies(specs.get(i))==null) continue; + double initial = BioModel.parseValue(bioModel.getParameter(GlobalConstants.INITIAL_STRING)); + double selectedThreshold = 0; + try { + if (sbml.getModel().getSpecies(specs.get(i)).isSetInitialAmount()) { + initial = sbml.getModel().getSpecies(specs.get(i)).getInitialAmount(); + } else { + initial = sbml.getModel().getSpecies(specs.get(i)).getInitialConcentration(); + } + } + catch (Exception e) { + } + double difference = Math.abs(selectedThreshold - initial); + for (Object threshold : conLevel.get(i)) { + double thisThreshold = Double.parseDouble((String) threshold); + double diff = Math.abs(thisThreshold - initial); + if (diff < difference) { + difference = diff; + selectedThreshold = thisThreshold; + } + } + LHPN.addInteger(specs.get(i), "" + ((int) selectedThreshold)); + } + for (String input : bioModel.getInputSpecies()) { + double value; + try { + if (sbml.getModel().getSpecies(input).isSetInitialAmount()) { + value = sbml.getModel().getSpecies(input).getInitialAmount(); + } else { + value = sbml.getModel().getSpecies(input).getInitialConcentration(); + } + } + catch (Exception e) { + value = 0; + } + LHPN.addInteger(input, "" + value); + } + for (String species : bioModel.getSpecies()) { + if (!specs.contains(species) && !bioModel.getInputSpecies().contains(species)) { + double value; + try { + if (sbml.getModel().getSpecies(species).isSetInitialAmount()) { + value = sbml.getModel().getSpecies(species).getInitialAmount(); + } else { + value = sbml.getModel().getSpecies(species).getInitialConcentration(); + } + } + catch (Exception e) { + value = 0; + } + LHPN.addInteger(species, "" + value); + } + } + for (int i = 0; i < specs.size(); i++) { + if (sbml.getModel().getSpecies(specs.get(i))==null) continue; + if (!biochemical.contains(specs.get(i)) && !bioModel.getInputSpecies().contains(specs.get(i))) { + int placeNum = 0; + int transNum = 0; + String previousPlaceName = specs.get(i) + placeNum; + placeNum++; + if (LHPN.getIntegers().get(specs.get(i)).equals("0")) { + LHPN.addPlace(previousPlaceName, true); + } + else { + LHPN.addPlace(previousPlaceName, false); + } + String number = "0"; + for (Object threshold : conLevel.get(i)) { + if (LHPN.getIntegers().get(specs.get(i)).equals("" + ((int) Double.parseDouble((String) threshold)))) { + LHPN.addPlace(specs.get(i) + placeNum, true); + } + else { + LHPN.addPlace(specs.get(i) + placeNum, false); + } + if (!(bioModel.isInput(specs.get(i)))) { + ArrayList proms = new ArrayList(); + Double global_np = BioModel.parseValue(bioModel.getParameter(GlobalConstants.STOICHIOMETRY_STRING)); + Double global_kd = BioModel.parseValue(bioModel.getParameter(GlobalConstants.KDECAY_STRING)); + Double np = global_np; + Double kd = global_kd; + for (Promoter p : network.getPromoters().values()) { + for (SpeciesInterface s : p.getOutputs()) { + if (s.getId().equals(specs.get(i))) { + proms.add(p.getId()); + } + } + + } + String rate = ""; + for (String promoter : proms) { + String promRate = abs.abstractOperatorSite(network.getPromoters().get(promoter)); +// for (String species : getSpecies()) { +// if (promRate.contains(species) && !LHPN.getIntegers().keySet().contains(species)) { +// double value; +// try { +// if (sbml.getModel().getSpecies(species).isSetInitialAmount()) { +// value = sbml.getModel().getSpecies(species).getInitialAmount(); +// } else { +// value = sbml.getModel().getSpecies(species).getInitialConcentration(); +// } +// } +// catch (Exception e) { +// value = 0; +// } +// LHPN.addInteger(species, "" + value); +// } +// } + if (rate.equals("")) { + rate = "(" + promRate + ")"; + } + else { + rate += "+(" + promRate + ")"; + } + } + if (!rate.equals("")) { + rate = "(" + np + "*(" + rate + "))"; + } + String reactionProductions = ""; + String reactionDegradations = ""; + ListOf reactions = sbml.getModel().getListOfReactions(); + for (int j = 0; j < sbml.getModel().getReactionCount(); j++) { + Reaction r = reactions.get(j); + if (!BioModel.isProductionReaction(r) && !BioModel.isDegradationReaction(r) + && !BioModel.isComplexReaction(r)) { + for (int k = 0; k < r.getReactantCount(); k++) { + if (r.getReactant(k).getSpecies().equals(specs.get(i))) { + KineticLaw law = r.getKineticLaw(); + HashMap parameters = new HashMap(); + for (String parameter : bioModel.getParameters()) { + parameters.put(parameter, bioModel.getParameter(parameter)); + } + for (int l = 0; l < law.getLocalParameterCount(); l++) { + parameters.put(law.getLocalParameter(l).getId(), "" + + law.getLocalParameter(l).getValue()); + } + if (r.isSetReversible() && law.getMath().getCharacter() == '-') { + reactionDegradations += "((" + + SBMLutilities.myFormulaToString(bioModel.replaceParams(law.getMath().getLeftChild(), + parameters)) + ")*" + r.getReactant(k).getStoichiometry() + + ") + "; + reactionProductions += "((" + + SBMLutilities.myFormulaToString(bioModel.replaceParams(law.getMath().getRightChild(), + parameters)) + ")*" + r.getReactant(k).getStoichiometry() + + ") + "; + } + else { + reactionDegradations += "((" + + SBMLutilities.myFormulaToString(bioModel.replaceParams(law.getMath(), + parameters)) + ")*" + r.getReactant(k).getStoichiometry() + + ") + "; + } + } + } + for (int k = 0; k < r.getProductCount(); k++) { + if (r.getProduct(k).getSpecies().equals(specs.get(i))) { + KineticLaw law = r.getKineticLaw(); + HashMap parameters = new HashMap(); + for (String parameter : bioModel.getParameters()) { + parameters.put(parameter, bioModel.getParameter(parameter)); + } + for (int l = 0; l < law.getLocalParameterCount(); l++) { + parameters.put(law.getLocalParameter(l).getId(), "" + + law.getLocalParameter(l).getValue()); + } + if (r.isSetReversible() && law.getMath().getCharacter() == '-') { + reactionProductions += "((" + + SBMLutilities.myFormulaToString(bioModel.replaceParams(law.getMath().getLeftChild(), + parameters)) + ")*" + r.getProduct(k).getStoichiometry() + + ") + "; + reactionDegradations += "((" + + SBMLutilities.myFormulaToString(bioModel.replaceParams(law.getMath().getRightChild(), + parameters)) + ")*" + r.getProduct(k).getStoichiometry() + + ") + "; + } + else { + reactionProductions += "((" + + SBMLutilities.myFormulaToString(bioModel.replaceParams(law.getMath(), + parameters)) + ")*" + r.getProduct(k).getStoichiometry() + + ") + "; + } + } + } + } + } + if (!reactionProductions.equals("")) { + reactionProductions = reactionProductions.substring(0, reactionProductions.length() - 3); + reactionProductions = reactionProductions.replaceAll(" ", ""); + } + if (!reactionDegradations.equals("")) { + reactionDegradations = reactionDegradations.substring(0, reactionDegradations.length() - 3); + reactionDegradations = reactionDegradations.replaceAll(" ", ""); + } + if (!rate.equals("") || !reactionProductions.equals("")) { + if (rate.equals("")) { + rate = "(" + reactionProductions + ")"; + } + else if (!reactionProductions.equals("")) { + rate = "(" + rate + "+" + reactionProductions + ")"; + } + LHPN.addTransition(specs.get(i) + "_trans" + transNum); + LHPN.addMovement(previousPlaceName, specs.get(i) + "_trans" + transNum); + LHPN.addMovement(specs.get(i) + "_trans" + transNum, specs.get(i) + placeNum); + LHPN.addIntAssign(specs.get(i) + "_trans" + transNum, specs.get(i), (String) threshold); + LHPN.addTransitionRate(specs.get(i) + "_trans" + transNum, rate + "/" + "(" + threshold + + "-" + number + "))"); + transNum++; + } + String specExpr = specs.get(i); + if (network.getSpecies().get(specs.get(i)).isSequesterable()) { + specExpr = abs.sequesterSpecies(specs.get(i), 0, false); + } + else if (network.getComplexMap().containsKey(specs.get(i))) { + specExpr = abs.abstractComplex(specs.get(i), 0, false); + } + if (!specExpr.equals(specs.get(i))) { + specExpr = "(" + specExpr + ")"; + } + kd = global_kd; + Reaction reaction = bioModel.getDegradationReaction(specs.get(i)); + if (reaction != null) { + LocalParameter param = reaction.getKineticLaw().getLocalParameter( + GlobalConstants.KDECAY_STRING); + if (param != null) { + kd = param.getValue(); + } + LHPN.addTransition(specs.get(i) + "_trans" + transNum); + LHPN.addMovement(specs.get(i) + placeNum, specs.get(i) + "_trans" + transNum); + LHPN.addMovement(specs.get(i) + "_trans" + transNum, previousPlaceName); + LHPN.addIntAssign(specs.get(i) + "_trans" + transNum, specs.get(i), number); + if (!reactionDegradations.equals("")) { + LHPN.addTransitionRate(specs.get(i) + "_trans" + transNum, "((" + specExpr + "*" + kd + ")" + + "+" + reactionDegradations + ")/" + "(" + threshold + "-" + number + ")"); + } + else { + LHPN.addTransitionRate(specs.get(i) + "_trans" + transNum, "(" + specExpr + "*" + kd + ")/" + + "(" + threshold + "-" + number + ")"); + } + transNum++; + } + else if (!reactionDegradations.equals("")) { + LHPN.addTransition(specs.get(i) + "_trans" + transNum); + LHPN.addMovement(specs.get(i) + placeNum, specs.get(i) + "_trans" + transNum); + LHPN.addMovement(specs.get(i) + "_trans" + transNum, previousPlaceName); + LHPN.addIntAssign(specs.get(i) + "_trans" + transNum, specs.get(i), number); + LHPN.addTransitionRate(specs.get(i) + "_trans" + transNum, "(" + reactionDegradations + + ")/" + "(" + threshold + "-" + number + ")"); + transNum++; + } + } + previousPlaceName = specs.get(i) + placeNum; + placeNum++; + number = (String) threshold; + } + } + } + if (lpnProperty.getString() != null) { + ArrayList sortedSpecies = new ArrayList(); + for (String s : bioModel.getSpecies()) { + sortedSpecies.add(s); + } + int i, j; + String index; + for (i = 1; i < sortedSpecies.size(); i++) { + index = sortedSpecies.get(i); + j = i; + while ((j > 0) && sortedSpecies.get(j - 1).length() < index.length()) { + sortedSpecies.set(j, sortedSpecies.get(j - 1)); + j--; + } + sortedSpecies.set(j, index); + } + for (String s : sortedSpecies) { + String replace = null; + if (network.getSpecies().get(s).isSequesterable()) { + replace = abs.sequesterSpecies(s, 0, false); + } + else if (network.getComplexMap().containsKey(s)) { + replace = abs.abstractComplex(s, 0, false); + } + if (replace != null && lpnProperty.getString().contains(s)) { + replace = "(" + replace + ")"; + lpnProperty.setString(lpnProperty.getString().replaceAll(s, replace)); + } + } + LHPN.addProperty(lpnProperty.getString()); + } + return LHPN; + } + + public static void convertLPN2PRISM(FileWriter logFile,LPN LPN,String filename, SBMLDocument sbml) { + File file = new File(filename); + try { + FileWriter out = new FileWriter(file); + out.write("ctmc\n"); + for (String var : LPN.getVariables()) { + int i=0; + Place place; + String lastValue=""; + while ((place = LPN.getPlace(var+i))!=null) { + Transition inTrans = place.getPreset()[0]; + ExprTree assign = inTrans.getAssignTree(var); + lastValue = assign.toString(); + i++; + } + Variable variable = LPN.getVariable(var); + String initValue = variable.getInitValue(); + initValue = Long.toString((Math.round(Double.valueOf(initValue)))); + if (lastValue.equals("")) { + out.write("const int "+var+"="+initValue+";\n"); + } else { + out.write("module "+var+"_def\n"); + out.write(" "+var+" : "+"[0.."+lastValue+"] init "+initValue+";\n"); + i=0; + while ((place = LPN.getPlace(var+i))!=null) { + Transition inTrans = place.getPreset()[0]; + ExprTree assign = inTrans.getAssignTree(var); + out.write(" [] "+var+"="+assign.toString()+" -> "); + boolean first = true; + for (Transition outTrans : place.getPostset()) { + assign = outTrans.getAssignTree(var); + ExprTree delay = outTrans.getDelayTree(); + String rate = delay.toString("prism"); + rate = rate.replace("exponential", ""); + if (!first) out.write(" + "); + out.write(rate+":("+var+"'="+assign.toString()+")"); + first = false; + } + out.write(";\n"); + i++; + } + out.write("endmodule\n"); + } + } + out.close(); + for (int i = 0; i < sbml.getModel().getConstraintCount(); i++) { + file = new File(filename.replace(".prism", ".pctl")); + out = new FileWriter(file); + out.write(SBMLutilities.convertMath2PrismProperty(sbml.getModel().getConstraint(i).getMath())); + out.close(); + } + } + catch (IOException e) { + //TODO: Leandro fix Me + //message.setErrorDialog("Error Writing File", "I/O error when writing PRISM file"); + } + } + + public void save(String filename) { + try { + String file = filename; + PrintStream p = new PrintStream(new FileOutputStream(filename)); + StringBuffer buffer = new StringBuffer(); + HashMap boolOrder = new HashMap(); + int i = 0; + boolean flag = false; + for (String s : booleans.keySet()) { + if (booleans.get(s) != null) { + if (booleans.get(s).isInput()) { + if (!flag) { + buffer.append(".inputs "); + flag = true; + } + buffer.append(s + " "); + boolOrder.put(s, i); + i++; + } + } + } + for (String s : continuous.keySet()) { + if (continuous.get(s) != null) { + if (continuous.get(s).isInput()) { + if (!flag) { + buffer.append(".inputs "); + flag = true; + } + buffer.append(s + " "); + } + } + } + for (String s : integers.keySet()) { + if (integers.get(s) != null) { + if (integers.get(s).isInput()) { + if (!flag) { + buffer.append(".inputs "); + flag = true; + } + buffer.append(s + " "); + } + } + } + if (flag) buffer.append("\n"); + flag = false; + for (String s : booleans.keySet()) { + if (booleans.get(s) != null) { + if (!flag) { + buffer.append(".outputs "); + flag = true; + } + if (booleans.get(s).isOutput()) { + buffer.append(s + " "); + boolOrder.put(s, i); + i++; + } + } + } + for (String s : continuous.keySet()) { + if (continuous.get(s) != null) { + if (continuous.get(s).isOutput()) { + if (!flag) { + buffer.append(".outputs "); + flag = true; + } + buffer.append(s + " "); + } + } + } + for (String s : integers.keySet()) { + if (integers.get(s) != null) { + if (integers.get(s).isOutput()) { + if (!flag) { + buffer.append(".outputs "); + flag = true; + } + buffer.append(s + " "); + } + } + } + if (flag) buffer.append("\n"); + flag = false; + for (String s : booleans.keySet()) { + if (booleans.get(s) != null) { + if (!flag) { + buffer.append(".internal "); + flag = true; + } + if (booleans.get(s).isInternal()) { + buffer.append(s + " "); + boolOrder.put(s, i); + i++; + } + } + } + for (String s : continuous.keySet()) { + if (continuous.get(s) != null) { + if (continuous.get(s).isInternal()) { + if (!flag) { + buffer.append(".internal "); + flag = true; + } + buffer.append(s + " "); + } + } + } + for (String s : integers.keySet()) { + if (integers.get(s) != null) { + if (integers.get(s).isInternal()) { + if (!flag) { + buffer.append(".internal "); + flag = true; + } + buffer.append(s + " "); + } + } + } + if (flag) buffer.append("\n"); + if (!transitions.isEmpty()) { + buffer.append(".dummy "); + for (String s : transitions.keySet()) { + buffer.append(s + " "); + } + buffer.append("\n"); + } + if (!continuous.isEmpty() || !integers.isEmpty()) { + buffer.append("#@.variables "); + for (String s : continuous.keySet()) { + buffer.append(s + " "); + } + for (String s : integers.keySet()) { + buffer.append(s + " "); + } + buffer.append("\n"); + } + if (!transitions.isEmpty()) { + flag = false; + for (Transition t : transitions.values()) { + if (t.isFail()) { + if (!flag) { + buffer.append("#@.failtrans "); + } + buffer.append(t.getLabel() + " "); + flag = true; + } + } + if (flag) { + buffer.append("\n"); + } + flag = false; + for (Transition t : transitions.values()) { + if (t.isPersistent()) { + if (!flag) { + buffer.append("#@.non_disabling "); + } + buffer.append(t.getLabel() + " "); + flag = true; + } + } + if (flag) { + buffer.append("\n"); + } + } + if (!places.isEmpty()) { + buffer.append("#|.places "); + for (String s : places.keySet()) { + buffer.append(s + " "); + } + buffer.append("\n"); + } + if (!booleans.isEmpty()) { + flag = false; + for (i = 0; i < boolOrder.size(); i++) { + for (String s : booleans.keySet()) { + if (boolOrder.get(s).equals(i)) { + if (!flag) { + buffer.append("#@.init_state ["); + flag = true; + } + if (booleans.get(s).getInitValue().equals("true")) { + buffer.append("1"); + } else if (booleans.get(s).getInitValue().equals( + "false")) { + buffer.append("0"); + } else { + buffer.append("X"); + } + } + } + } + if (flag) { + buffer.append("]\n"); + } + } + if (!transitions.isEmpty()) { + buffer.append(".graph\n"); + for (Transition t : transitions.values()) { + for (Place s : t.getPreset()) { + buffer.append(s.getName() + " " + t.getLabel() + "\n"); + } + for (Place s : t.getPostset()) { + buffer.append(t.getLabel() + " " + s.getName() + "\n"); + } + } + } + flag = false; + if (!places.keySet().isEmpty()) { + for (Place place : places.values()) { + if (place.isMarked()) { + if (!flag) { + buffer.append(".marking {"); + flag = true; + } + buffer.append(place.getName() + " "); + } + } + if (flag) { + buffer.append("}\n"); + } + } + if (properties != null && !properties.isEmpty()) { +// if (!properties.contains("none")) +// properties.add(0, "none"); + for (String property : properties) { + buffer.append("#@.property "); + buffer.append(property + "\n"); + } + } + if (!continuous.isEmpty() || !integers.isEmpty()) { + buffer.append("#@.init_vals {"); + for (Variable var : continuous.values()) { + buffer.append("<" + var.getName() + "=" + + var.getInitValue() + ">"); + } + for (Variable var : integers.values()) { + buffer.append("<" + var.getName() + "=" + + var.getInitValue() + ">"); + } + if (!continuous.isEmpty()) { + buffer.append("}\n#@.init_rates {"); + for (Variable var : continuous.values()) { + buffer.append("<" + var.getName() + "=" + + var.getInitRate() + ">"); + } + } + buffer.append("}\n"); + } + if (!transitions.isEmpty()) { + flag = false; + for (Transition t : transitions.values()) { + if (t.getEnabling() != null && !t.getEnabling().equals("")) { + if (!flag) { + buffer.append("#@.enablings {"); + flag = true; + } + buffer.append("<" + t.getLabel() + "=[" + + t.getEnabling() + "]>"); + } + } + if (flag) { + buffer.append("}\n"); + } + flag = false; + for (Transition t : transitions.values()) { + HashMap contAssign = t.getContAssignments(); + if (!contAssign.isEmpty()) { + if (!flag) { + buffer.append("#@.assignments {"); + flag = true; + } + for (String var : contAssign.keySet()) { + buffer.append("<" + t.getLabel() + "=[" + var + ":=" + + contAssign.get(var) + "]>"); + } + } + HashMap intAssign = t.getIntAssignments(); + if (!intAssign.isEmpty()) { + if (!flag) { + buffer.append("#@.assignments {"); + flag = true; + } + for (String var : intAssign.keySet()) { + buffer.append("<" + t.getLabel() + "=[" + var + ":=" + + intAssign.get(var) + "]>"); + } + } + } + if (flag) { + buffer.append("}\n"); + } + flag = false; + for (Transition t : transitions.values()) { + HashMap rateAssign = t.getRateAssignments(); + for (String var : rateAssign.keySet()) { + if (!var.equals("")) { + if (!flag) { + buffer.append("#@.rate_assignments {"); + flag = true; + } + buffer.append("<" + t.getLabel() + "=[" + var + ":=" + + t.getRateAssignment(var) + "]>"); + } + } + } + if (flag) { + buffer.append("}\n"); + } + flag = false; + for (Transition t : transitions.values()) { + if (t.containsDelay()) { + if (!flag) { + buffer.append("#@.delay_assignments {"); + flag = true; + } + buffer.append("<" + t.getLabel() + "=[" + t.getDelay() + + "]>"); + } + } + if (flag) { + buffer.append("}\n"); + } + flag = false; + for (Transition t : transitions.values()) { + if (t.containsPriority()) { + if (!flag) { + buffer.append("#@.priority_assignments {"); + flag = true; + } + buffer.append("<" + t.getLabel() + "=[" + + t.getPriority() + "]>"); + } + } + if (flag) { + buffer.append("}\n"); + } + } + flag = false; + for (Transition t : transitions.values()) { + HashMap boolAssign = t.getBoolAssignments(); + for (String var : boolAssign.keySet()) { + if (!flag) { + buffer.append("#@.boolean_assignments {"); + flag = true; + } + buffer.append("<" + t.getLabel() + "=[" + var + ":=" + + boolAssign.get(var) + "]>"); + } + } + if (flag) { + buffer.append("}\n"); + } + buffer.append("#@.continuous "); + for (String s : continuous.keySet()) { + buffer.append(s + " "); + } + buffer.append("\n"); + if (buffer.toString().length() > 0) { + buffer.append(".end\n"); + } + p.print(buffer); + p.close(); + message.setLog("Saving:\n" + file + "\n"); + this.notifyObservers(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void load(String filename) throws BioSimException { + StringBuffer data = new StringBuffer(); + label = filename.split(separator)[filename.split(separator).length - 1].replace(".lpn",""); + try { + BufferedReader in = new BufferedReader(new FileReader(filename)); + String str; + while ((str = in.readLine()) != null) { + data.append(str + "\n"); + } + in.close(); + } catch (IOException e) { + e.printStackTrace(); + throw new IllegalStateException("Error opening file"); + } + + parseProperty(data); + parsePlaces(data); + parseControlFlow(data); + parseVars(data); + parseIntegers(data); + parseInOut(data); + parseMarking(data); + boolean error = parseEnabling(data); + error = parseAssign(data, error); + error = parseRateAssign(data, error); + error = parseDelayAssign(data, error); + error = parsePriorityAssign(data, error); + error = parseBooleanAssign(data, error); + error = parseTransitionRate(data, error); + parseFailTransitions(data); + parsePersistentTransitions(data); + + if (!error) { + throw new BioSimException("Invalid Expressions", + "The input file contained invalid expressions. See console for details."); + } + } + + public void printDot(String filename) { + try { + String file = filename; + PrintStream p = new PrintStream(new FileOutputStream(filename)); + StringBuffer buffer = new StringBuffer(); + buffer.append("digraph G {\nsize=\"7.5,10\"\n"); + buffer.append("Inits [shape=plaintext,label=\""); + for (Variable v : booleans.values()) { + buffer.append(v.getName() + " = " + v.getInitValue() + "\\n"); + } + for (Variable v : integers.values()) { + buffer.append(v.getName() + " = " + v.getInitValue() + "\\n"); + } + for (Variable v : continuous.values()) { + buffer.append(v.getName() + " = " + v.getInitValue() + "\\n" + v.getName() + "' = " + v.getInitRate() + "\\n"); + } + buffer.append("\"]\n"); + for (Transition t : transitions.values()) { + buffer.append(t.getLabel() + " [shape=plaintext,label=\"" + t.getLabel()); + if (t.containsEnabling()) { + if (t.isPersistent()) { + buffer.append("\\n{" + t.getEnabling() + "}"); + } + else { + buffer.append("\\n{" + t.getEnabling() + "}"); + } + } + if (t.containsDelay()) { + buffer.append("\\n[" + t.getDelay() + "]"); + } + if (t.containsAssignment()) { + buffer.append("\\n<"); + boolean flag = false; + if (t.containsBooleanAssignment()) { + HashMap map = t.getBoolAssignments(); + for (String v : map.keySet()) { + if (flag) { + buffer.append(","); + } + else { + flag = true; + } + buffer.append(v + ":=" + + t.getBoolAssignment(v)); + } + } + if (t.containsContinuousAssignment()) { + HashMap map = t.getContAssignments(); + for (String v : map.keySet()) { + if (flag) { + buffer.append(","); + } + else { + flag = true; + } + buffer.append(v + ":=" + t.getContAssignment(v)); + } + } + if (t.containsIntegerAssignment()) { + HashMap map = t.getIntAssignments(); + for (String v : map.keySet()) { + if (flag) { + buffer.append(","); + } + else { + flag = true; + } + buffer.append(v + ":=" + t.getIntAssignment(v)); + } + } + if (t.containsRateAssignment()) { + HashMap map = t.getRateAssignments(); + for (String v : map.keySet()) { + if (flag) { + buffer.append(","); + } + else { + flag = true; + } + buffer.append(v + "':=" + t.getRateAssignment(v)); + } + } + buffer.append(">"); + } + buffer.append("\""); + if (t.isFail()&&t.isPersistent()) { + buffer.append(",fontcolor=purple"); + } + else if (t.isFail()) { + buffer.append(",fontcolor=red"); + } + else if (t.isPersistent()) { + buffer.append(",fontcolor=blue"); + } + buffer.append("];\n"); + } + for (Place place : places.values()) { + buffer.append(place.getName() + " [label=\"" + place.getName() + "\"];\n" + place.getName() + + " [shape=circle,width=0.40,height=0.40]\n"); + if (place.isMarked()) { + buffer + .append(place.getName() + + " [height=.3,width=.3,peripheries=2,style=filled,color=black,fontcolor=white];\n"); + } + Transition[] postset = place.getPostset(); + for (Transition t : postset) { + buffer.append(place.getName() + " -> " + t.getLabel() + "\n"); + } + } + for (Transition t : transitions.values()) { + Place[] postset = t.getPostset(); + for (Place place : postset) { + buffer.append(t.getLabel() + " -> " + place.getName() + "\n"); + } + } + buffer.append("}\n"); + p.print(buffer); + p.close(); + message.setLog("Saving:\n" + file + "\n"); + this.notifyObservers(message); + } + catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + + public void addTransition(String name) { + Transition trans = new Transition(name, tranIndex++, this); + transitions.put(name, trans); + } + +// public void addTransition(String name, Properties prop) { +// Transition trans = new Transition(name, variables, this); +// for (String p : prop.getProperty("preset").split("\\s")) { +// trans.addPreset(places.get(p)); +// } +// for (String p : prop.getProperty("postset").split("\\s")) { +// trans.addPostset(places.get(p)); +// } +// transitions.put(name, trans); +// } + + public void addTransition(Transition t) { + transitions.put(t.getLabel(), t); + } + + public String insertPlace(Boolean ic) { + String name = ""; + do { + name = "ip" + implicitPlaceCount++; + } while (getPlace(name)!=null); + Place place = new Place(name, ic); + places.put(name, place); + return name; + } + + public void addPlace(String name, Boolean ic) { + Place place = new Place(name, ic); + places.put(name, place); + } + + public void addEnabling(String transition, String enabling) { + transitions.get(transition).addEnabling(enabling); + } + + public void addProperty(String prop) { + properties.add(prop); + } + + public void removeProperty(String prop) { + properties.remove(prop); + } + + public void addMovement(String fromName, String toName) { + if (isTransition(fromName)) { + transitions.get(fromName).addPostset(places.get(toName)); + places.get(toName).addPreset(transitions.get(fromName)); + } else { + transitions.get(toName).addPreset(places.get(fromName)); + places.get(fromName).addPostset(transitions.get(toName)); + } + } + + public void addInput(String name, String ic) { + Variable var = new Variable(name, "boolean", ic, Variable.INPUT); + booleans.put(name, var); + if (!variables.contains(var)) { + variables.add(var); + } + } + + public void addInput(String name, String type, String ic) { + Variable var = new Variable(name, type, ic, Variable.INPUT); + if (type.equals("boolean")) + booleans.put(name, var); + else if (type.equals("integer")) + integers.put(name, var); + else if (type.equals("continuous")) + continuous.put(name, var); + if (!variables.contains(var)) { + variables.add(var); + } + } + + public void addOutput(String name, String ic) { + Variable var = new Variable(name, "boolean", ic, Variable.OUTPUT); + booleans.put(name, var); + if (!variables.contains(var)) { + variables.add(var); + } + } + + public void addOutput(String name, String type, String ic) { + Variable var = new Variable(name, type, ic, Variable.OUTPUT); + if (type.equals("boolean")) + booleans.put(name, var); + else if (type.equals("integer")) + integers.put(name, var); + else if (type.equals("continuous")) + continuous.put(name, var); + if (!variables.contains(var)) { + variables.add(var); + } + } + + public void addInternal(String name, String type, String ic) { + Variable var = new Variable(name, type, ic, Variable.INTERNAL); + if (type.equals("boolean")) + booleans.put(name, var); + else if (type.equals("integer")) + integers.put(name, var); + else if (type.equals("continuous")) + continuous.put(name, var); + if (!variables.contains(var)) { + variables.add(var); + } + } + + + public void addBoolean(String name, String ic) { + Variable var = new Variable(name, "boolean", ic); + booleans.put(name, var); + if (!variables.contains(var)) { + variables.add(var); + } + } + + public void addContinuous(String name) { + // Check if the name is already present. If not, add the variable. + + if(!continuous.containsKey(name)){ + Variable var = new Variable(name, "continuous"); + continuous.put(name, var); + } + +// Variable var = new Variable(name, "continuous"); +// continuous.put(name, var); +// if (!variables.contains(var)) { +// variables.add(var); +// } + } + + public void addContinuous(String name, Properties initCond) { + Variable contVar = null; + + // Search for the Variable. + for(Variable var : continuous.values()){ + if(var.getName().equals(name)){ + contVar = var; + } + } + + // If contVar contains null, then a previous existing Variable was not found. + if(contVar != null){ + contVar.addInitCond(initCond); + } + else{ + continuous.put(name, new Variable(name, "continuous", initCond)); + } + + } + + + public void addContinuousInput(String name, Properties initCond) { + Variable contVar = null; + + // Search for the Variable. + for(Variable var : continuous.values()){ + if(var.getName().equals(name)){ + contVar = var; + } + } + + // If contVar contains null, then a previous existing Variable was not found. + if(contVar != null){ + contVar.addInitCond(initCond); + } + else{ + continuous.put(name, new Variable(name, "continuous", initCond, Variable.INPUT)); + } + + } + + public void addContinuousOutput(String name, Properties initCond) { + Variable contVar = null; + + // Search for the Variable. + for(Variable var : continuous.values()){ + if(var.getName().equals(name)){ + contVar = var; + } + } + + // If contVar contains null, then a previous existing Variable was not found. + if(contVar != null){ + contVar.addInitCond(initCond); + } + else{ + continuous.put(name, new Variable(name, "continuous", initCond, Variable.OUTPUT)); + } + + } + + public void addContinuous(String name, String initVal, String initRate) { + Properties initCond = new Properties(); + initCond.setProperty("value", initVal); + initCond.setProperty("rate", initRate); + Variable var = new Variable(name, "continuous", initCond); + continuous.put(name, var); +// if (!variables.contains(var)) { +// variables.add(var); +// } + } + + public void addInteger(String name, String ic) { + Variable var = new Variable(name, "integer", ic); + integers.put(name, var); + if (!variables.contains(var)) { + variables.add(var); + } + } + + public void addIntegerInput(String name, String ic) { + Variable var = new Variable(name, "integer", ic, Variable.INPUT); + integers.put(name, var); + if (!variables.contains(var)) { + variables.add(var); + } + } + + public void addIntegerOutput(String name, String ic) { + Variable var = new Variable(name, "integer", ic, Variable.OUTPUT); + integers.put(name, var); + if (!variables.contains(var)) { + variables.add(var); + } + } + + public void addTransitionRate(String transition, String rate) { + transitions.get(transition).addDelay("exponential(" + rate + ")"); + } + + public void addBoolAssign(String transition, String variable, + String assignment) { + if (!variables.contains(variable)) { + addOutput(variable, "unknown"); + } + transitions.get(transition).addIntAssign(variable, assignment); + } + + public void addRateAssign(String transition, String variable, String rate) { + transitions.get(transition).addRateAssign(variable, rate); + } + + public void addIntAssign(String transition, String variable, String assign) { + transitions.get(transition).addIntAssign(variable, assign); + } + + public void changePlaceName(String oldName, String newName) { + places.get(oldName).setName(newName); + places.put(newName, places.get(oldName)); + places.remove(oldName); + } + + public void changeTransitionName(String oldName, String newName) { + transitions.get(oldName).setName(newName); + transitions.put(newName, transitions.get(oldName)); + transitions.remove(oldName); + } + + public void changeDelay(String t, String delay) { + transitions.get(t).addDelay(delay); + } + + public void changePriority(String t, String priority) { + transitions.get(t).addDelay(priority); + } + + public void changeInitialMarking(String p, boolean marking) { + places.get(p).setMarking(marking); + } + + public void changeVariableName(String oldName, String newName) { + if (isContinuous(oldName)) { + continuous.put(newName, continuous.get(oldName)); + continuous.remove(oldName); + } else if (isBoolean(oldName)) { + booleans.put(newName, booleans.get(oldName)); + booleans.remove(oldName); + } else if (isInteger(oldName)) { + integers.put(newName, integers.get(oldName)); + integers.remove(oldName); + } + } + + public void changeContInitCond(String var, Properties initCond) { + continuous.get(var).addInitCond(initCond); + } + + public void changeIntegerInitCond(String var, String initCond) { + integers.get(var).addInitValue(initCond); + } + + public String[] getAllIDs() { + String[] ids = new String[transitions.size() + places.size() + + variables.size()]; + int i = 0; + for (String t : transitions.keySet()) { + ids[i++] = t; + } + for (String p : places.keySet()) { + ids[i++] = p; + } + for (Variable v : variables) { + ids[i++] = v.getName(); + } + return ids; + } + + public ArrayList getProperties() { + return properties; + } + + public String[] getTransitionList() { + String[] transitionList = new String[transitions.size()]; + int i = 0; + for (String t : transitions.keySet()) { + transitionList[i++] = t; + } + return transitionList; + } + + /** + * Returns all transitions of this LPN. + * @return + */ + public Transition[] getAllTransitions() { + if (allTransitions == null) { + allTransitions = new Transition[transitions.size()]; + for (String t: transitions.keySet()) { + allTransitions[transitions.get(t).getIndex()] = transitions.get(t); + } + return allTransitions; + } + return allTransitions; + } + + public Transition getTransition(int index) { + return getAllTransitions()[index]; + } + + public ArrayList getTransitionListArrayList() { + ArrayList transitionList = new ArrayList(transitions.size()); + int i = 0; + for (String t: transitions.keySet()) { + transitionList.add(i++, t); + } + return transitionList; + } + + public Transition getTransition(String transition) { + return transitions.get(transition); + } + + public boolean isRandomBoolAssignTree(String transition, String variable) { + if (transitions.get(transition).getBoolAssignTree(variable) == null) + return false; + if (transitions.get(transition).getBoolAssignTree(variable).op.equals("exponential") + || transitions.get(transition).getBoolAssignTree(variable).op.equals("uniform")) { + return true; + } + return false; + } + + public boolean isRandomContAssignTree(String transition, String variable) { + if (transitions.get(transition).getContAssignTree(variable) == null) + return false; + if (transitions.get(transition).getContAssignTree(variable).op.equals("exponential") + || transitions.get(transition).getContAssignTree(variable).op.equals("uniform")) { + return true; + } + return false; + } + + public boolean isRandomIntAssignTree(String transition, String variable) { + if (transitions.get(transition).getIntAssignTree(variable) == null) + return false; + if (transitions.get(transition).getIntAssignTree(variable).op.equals("exponential") + || transitions.get(transition).getIntAssignTree(variable).op.equals("uniform")) { + return true; + } + return false; + } + + public boolean isExpTransitionRateTree(String transition) { + if (transitions.get(transition).getDelayTree() == null) + return false; + if (transitions.get(transition).getDelayTree().op.equals("exponential")) { + return true; + } + return false; + } + + public ExprTree getTransitionRateTree(String transition) { + if (transitions.get(transition).getDelayTree() == null) + return null; + if (transitions.get(transition).getDelayTree().op.equals("exponential")) { + return transitions.get(transition).getDelayTree().r1; + } + return null; + } + + public ExprTree getDelayTree(String transition) { + if (transitions.get(transition).getDelayTree() == null) { + return null; + } + return transitions.get(transition).getDelayTree(); + } + + public ExprTree getEnablingTree(String transition) { + return transitions.get(transition).getEnablingTree(); + } + + public String getLabel() { + return label; + } + + public int getLpnIndex() { + return lpnIndex; + } + + public String[] getPlaceList() { + placeList = new String[places.size()]; + int i = 0; + for (String t : places.keySet()) { + placeList[i++] = t; + } + return placeList; + } + +// public ArrayList getAllPlaces() { +// if(placeList == null) { +// int i = 0; +// for (String t: places.keySet()) { +// placeList.add(i++, t); +// } +// return placeList; +// } +// else +// return placeList; +// +// } + + public Place getPlace(String place) { + return places.get(place); + } + + public String[] getPreset(String name) { + if (isTransition(name)) { + String[] preset = new String[transitions.get(name).getPreset().length]; + int i = 0; + for (Place p : transitions.get(name).getPreset()) { + preset[i++] = p.getName(); + } + return preset; + } else if (places.containsKey(name)) { + String[] preset = new String[places.get(name).getPreset().length]; + int i = 0; + for (Transition t : places.get(name).getPreset()) { + preset[i++] = t.getLabel(); + } + return preset; + } else { + return null; + } + } + + public int[] getPresetIndex(String name) { + if (isTransition(name)) { + int[] preset = new int[transitions.get(name).getPreset().length]; + Place[] presetPlaces = transitions.get(name).getPreset(); + for (int i=0; i movements = new ArrayList(); + for (Transition t : transitions.values()) { + for (Place p : t.getPostset()) { + movements.add(t.getLabel() + " " + p.getName()); + } + for (Place p : t.getPreset()) { + movements.add(p.getName() + " " + t.getLabel()); + } + } + String[] array = new String[movements.size()]; + int i = 0; + for (String s : movements) { + array[i++] = s; + } + return array; + } + + public boolean getInitialMarking(String place) { + return places.get(place).isMarked(); + } + + public int[] getInitialMarkingsArray() { + int[] initialMarkings = new int[this.getPlaceList().length]; + int i = 0; + for (String place : this.getPlaceList()) { + if(places.get(place).isMarked()) { + initialMarkings[i] = 1; + } + else { + initialMarkings[i] = 0; + } + i++; + } + return initialMarkings; + } + + public String[] getVariables() { + String[] vars = new String[variables.size()+continuous.keySet().size()]; + int i = 0; + for (Variable v : variables) { + vars[i++] = v.getName(); + } + + for(String contName : continuous.keySet()){ + vars[i++] = contName; + } + + return vars; + } + + public DualHashMap getVarIndexMap() { + + if(_varIndexMap == null){ + + int i = 0; + HashMap varIndexHashMap = new HashMap(); + for (Variable v: variables) { + varIndexHashMap.put(v.getName(), i); + i++; + } + DualHashMap varIndexMap = new DualHashMap(varIndexHashMap, variables.size()); + + _varIndexMap = varIndexMap; + + return varIndexMap; + } + return _varIndexMap; + } + + /** + * Gives a map that associates the name of a continuous variable to its index. + * @return + * The map that associates the continuous variable and name. + */ + public DualHashMap getContinuousIndexMap(){ + + if(_continuousIndexMap == null){ + int i=allTransitions.length; + HashMap contVarIndexHashMap = new HashMap(); + for(Variable v : continuous.values()){ + contVarIndexHashMap.put(v.getName(), i); + i++; + } + DualHashMap contIndexMap = + new DualHashMap (contVarIndexHashMap, variables.size()); + + _continuousIndexMap = contIndexMap; + return contIndexMap; + } + return _continuousIndexMap; + } + + public HashMap getAllVarsWithValuesAsString(int[] varValueVector) { + DualHashMap varIndexMap = this.getVarIndexMap(); + HashMap varToValueMap = new HashMap(); + // varValue is a map between variable names and their values. + for (int i = 0; i < varValueVector.length; i++) { + String var = varIndexMap.getKey(i); + varToValueMap.put(var, varValueVector[i] + ""); + } + return varToValueMap; + } + + public HashMap getAllVarsWithValuesAsInt(int[] varValueVector) { + DualHashMap varIndexMap = this.getVarIndexMap(); + HashMap varToValueMap = new HashMap(); + // varValue is map between variable names and their values. + for (int i = 0; i < varValueVector.length; i++) { + String var = varIndexMap.getKey(i); + varToValueMap.put(var, varValueVector[i]); + } + return varToValueMap; + } + + public Variable getVariable(String name) { + if (isBoolean(name)) { + return booleans.get(name); + } else if (isContinuous(name)) { + return continuous.get(name); + } else if (isInteger(name)) { + return integers.get(name); + } + return null; + } + + public Variable getVariable(int index){ + return variables.get(index); + } + + public int getVariableIndex(String name){ + return getVarIndexMap().get(name); + } + + public String getContVarName(int index){ + //int counter = 0; + + // The index of the continuous variable is determined by + // the order it is returned by the 'continuous' fields + // iterator. +// for(String name : continuous.keySet()){ +// if(counter == index){ +// return name; +// } +// counter++; +// } + + DualHashMap variableMap = getContinuousIndexMap(); + + //return null; + return variableMap.getKey(index); + } + + public Variable getContVar(int index){ + + // Convert the index into a name. + String name = getContVarName(index); + + return continuous.get(name); + } + + public int getContVarIndex(String name){ + DualHashMap contVarIndecies = getContinuousIndexMap(); + return contVarIndecies.getValue(name); + } + + public HashMap getBoolInputs() { + HashMap inputs = new HashMap(); + for (Variable v : booleans.values()) { + if (!v.isOutput()) { + inputs.put(v.getName(), v.getInitValue()); + } + } + return inputs; + } + + public HashMap getBoolOutputs() { + HashMap outputs = new HashMap(); + for (Variable v : booleans.values()) { + if (v.isOutput()) { + outputs.put(v.getName(), v.getInitValue()); + } + } + return outputs; + } + + public HashMap getAllInputs() { + HashMap inputs = new HashMap(); + for (Variable v : booleans.values()) { + if (v.isInput()) { + inputs.put(v.getName(), v.getInitValue()); + } + } + for (Variable v : integers.values()) { + if (v.isInput()) { + inputs.put(v.getName(), v.getInitValue()); + } + } + for (Variable v : continuous.values()) { + if (v.isInput()) { + inputs.put(v.getName(), v.getInitValue()); + } + } + + return inputs; + } + + public HashMap getAllInternals() { + HashMap internals = new HashMap(); + for (Variable v : booleans.values()) { + if (v.isInternal()) { + internals.put(v.getName(), v.getInitValue()); + } + } + for (Variable v : integers.values()) { + if (v.isInternal()) { + internals.put(v.getName(), v.getInitValue()); + } + } + for (Variable v : continuous.values()) { + if (v.isInternal()) { + internals.put(v.getName(), v.getInitValue()); + } + } + return internals; + } + + public HashMap getAllOutputs() { + HashMap outputs = new HashMap(); + for (Variable v : booleans.values()) { + if (v.isOutput()) { + outputs.put(v.getName(), v.getInitValue()); + } + } + for (Variable v : integers.values()) { + if (v.isOutput()) { + outputs.put(v.getName(), v.getInitValue()); + } + } + for (Variable v : continuous.values()) { + if (v.isOutput()) { + outputs.put(v.getName(), v.getInitValue()); + } + } + return outputs; + } + + public HashMap getBooleans() { + HashMap bools = new HashMap(); + for (Variable v : booleans.values()) { + bools.put(v.getName(), v.getInitValue()); + } + return bools; + } + + public HashMap getContinuous() { + HashMap tempCont = new HashMap(); + for (Variable v : continuous.values()) { + Properties prop = new Properties(); + prop.setProperty("value", v.getInitValue()); + prop.setProperty("rate", v.getInitRate()); + tempCont.put(v.getName(), prop); + } + return tempCont; + } + + public HashMap getIntegers() { + HashMap tempInt = new HashMap(); + for (Variable v : integers.values()) { + tempInt.put(v.getName(), v.getInitValue()); + } + return tempInt; + } + + public String[] getBooleanVars() { + String[] vars = new String[booleans.size()]; + int i = 0; + for (String v : booleans.keySet()) { + vars[i++] = v; + } + return vars; + } + + public String[] getBooleanVars(String transition) { + Set set = transitions.get(transition).getBoolAssignments() + .keySet(); + String[] array = new String[set.size()]; + int i = 0; + for (String s : set) { + array[i++] = s; + } + return array; + } + + public String[] getContVars() { + String[] vars = new String[continuous.size()]; + int i = 0; + for (String v : continuous.keySet()) { + vars[i++] = v; + } + return vars; + } + + public String[] getContVars(String transition) { + Set set = transitions.get(transition).getContAssignments() + .keySet(); + String[] array = new String[set.size()]; + int i = 0; + for (String s : set) { + array[i++] = s; + } + return array; + } + + public String[] getRateVars(String transition) { + Set set = transitions.get(transition).getRateAssignments() + .keySet(); + String[] array = new String[set.size()]; + int i = 0; + for (String s : set) { + array[i++] = s; + } + return array; + } + + public String[] getIntVars() { + String[] vars = new String[integers.size()]; + int i = 0; + for (String v : integers.keySet()) { + vars[i++] = v; + } + return vars; + } + + public String[] getIntVars(String transition) { + Set set = transitions.get(transition).getIntAssignments() + .keySet(); + String[] array = new String[set.size()]; + int i = 0; + for (String s : set) { + array[i++] = s; + } + return array; + } + + public String getInitialVal(String var) { + if (isBoolean(var)) { + return booleans.get(var).getInitValue(); + } else if (isInteger(var)) { + return integers.get(var).getInitValue(); + } else { + return continuous.get(var).getInitValue(); + } + } + + public String getInitialRate(String var) { + if (isContinuous(var)) { + return continuous.get(var).getInitRate(); + } + return null; + } + + /** + * This method converts all variable values (boolean, continuous and integer) to int. + * @param var + * @return + */ + public int getInitVariableVector(String var) { + if (isBoolean(var)) { + if(booleans.get(var).getInitValue().equals("true")) + return 1; + return 0; + } + else if (isInteger(var)) { + String initValue = integers.get(var).getInitValue(); + if (initValue.contains(",")) { + initValue = initValue.split(",")[0].replace("[", ""); + } + return Integer.parseInt(initValue); + } + else { + // Continuous variable is not accepted here. + // return (int) Double.parseDouble(continuous.get(var).getInitValue()); + System.out.println(var + " is neither boolean or integer variable. "); + new NullPointerException().printStackTrace(); + System.exit(1); + return 0; + } + } + + public String getBoolAssign(String transition, String variable) { + return transitions.get(transition).getBoolAssignment(variable); + } + + public ExprTree getBoolAssignTree(String transition, String variable) { + return transitions.get(transition).getBoolAssignTree(variable); + } + + public String getContAssign(String transition, String variable) { + return transitions.get(transition).getContAssignment(variable); + } + + public ExprTree getContAssignTree(String transition, String variable) { + return transitions.get(transition).getContAssignTree(variable); + } + + public String getRateAssign(String transition, String variable) { + return transitions.get(transition).getRateAssignment(variable); + } + + public ExprTree getRateAssignTree(String transition, String variable) { + return transitions.get(transition).getRateAssignTree(variable); + } + + public String getIntAssign(String transition, String variable) { + return transitions.get(transition).getIntAssignment(variable); + } + + public ExprTree getIntAssignTree(String transition, String variable) { + return transitions.get(transition).getIntAssignTree(variable); + } + + public void removeTransition(String name) { + if (!transitions.containsKey(name)) { + return; + } + for (Place p : transitions.get(name).getPreset()) { + removeMovement(p.getName(), name); + } + for (Place p : transitions.get(name).getPostset()) { + removeMovement(name, p.getName()); + } + transitions.remove(name); + } + + public void removePlace(String name) { + if (name != null && places.containsKey(name)) { + for (Transition t : places.get(name).getPreset()) { + removeMovement(t.getLabel(), name); + } + for (Transition t : places.get(name).getPostset()) { + removeMovement(name, t.getLabel()); + } + places.remove(name); + } + } + + public void renamePlace(String oldName, String newName) { + if (oldName != null && places.containsKey(oldName)) { + places.put(newName, places.get(oldName)); + places.get(newName).changeName(newName); + places.remove(oldName); + } + } + + public void renameTransition(String oldName, String newName) { + if (oldName != null && transitions.containsKey(oldName)) { + transitions.put(newName, transitions.get(oldName)); + transitions.get(newName).changeName(newName); + transitions.remove(oldName); + } + } + + public void removeMovement(String from, String to) { + if (isTransition(from)) { + transitions.get(from).removePostset(places.get(to)); + places.get(to).removePreset(transitions.get(from)); + } else { + transitions.get(to).removePreset(places.get(from)); + places.get(from).removePostset(transitions.get(to)); + } + } + + public void removeInput(String name) { + if (name != null && booleans.containsKey(name)) { + booleans.remove(name); + variables.remove(booleans.get(name)); + } + } + + public void removeBoolean(String name) { + if (name != null && booleans.containsKey(name)) { + booleans.remove(name); + variables.remove(booleans.get(name)); + } + } + + public void removeOutput(String name) { + if (name != null && booleans.containsKey(name)) { + booleans.remove(name); + variables.remove(booleans.get(name)); + } + } + + public void removeContinuous(String name) { + if (name != null && continuous.containsKey(name)) { + continuous.remove(name); + variables.remove(continuous.get(name)); + } + } + + public void removeInteger(String name) { + if (name != null && integers.containsKey(name)) { + integers.remove(name); + variables.remove(integers.get(name)); + } + } + + public boolean removeVar(String name) { + for (Transition t : transitions.values()) { + if (t.containsAssignment(name)) { + return false; + } + } + if (name != null && continuous.containsKey(name)) { + removeContinuous(name); + } else if (name != null && booleans.containsKey(name)) { + removeBoolean(name); + } else if (name != null && integers.containsKey(name)) { + removeInteger(name); + } else { + for (Variable v : variables) { + if (v.getName().equals(name)) { + variables.remove(v); + break; + } + } + } + return true; + } + + public void removeAllAssignVar(String name) { + for (Transition t : transitions.values()) { + if (t.containsAssignment(name)) { + t.removeAssignment(name); + } + } + } + + public void setLabel(String label) { + this.label = label; + } + + public void setLpnIndex(int index) { + this.lpnIndex = index; + } + + public boolean isTransition(String name) { + return transitions.containsKey(name); + } + + public boolean isInput(String var) { + if (isContinuous(var)) { + return continuous.get(var).isInput(); + } + else if (isInteger(var)) { + return integers.get(var).isInput(); + } + else if (isBoolean(var)) { + return booleans.get(var).isInput(); + } + return false; + } + + public boolean isOutput(String var) { + if (isContinuous(var)) { + return continuous.get(var).isOutput(); + } + else if (isInteger(var)) { + return integers.get(var).isOutput(); + } + else if (isBoolean(var)) { + return booleans.get(var).isOutput(); + } + return false; + } + + public boolean isBoolean(String var) { + return booleans.containsKey(var); + } + + public boolean isContinuous(String var) { + return continuous.containsKey(var); + } + + public boolean isInteger(String var) { + return integers.containsKey(var); + } + + public boolean isMarked(String place) { + return places.get(place).isMarked(); + } + + public boolean containsTransition(String name) { + return transitions.containsKey(name); + } + + public boolean containsMovement(String name) { + if (places.containsKey(name)) { + return places.get(name).isConnected(); + } + return transitions.get(name).isConnected(); + } + + public boolean containsMovement(String from, String to) { + if (isTransition(from)) { + return transitions.get(from).containsPostset(to); + } + return places.get(from).containsPostset(to); + } + + + private void parseProperty(StringBuffer data) { + Pattern pattern = Pattern.compile(PROPERTY); + Matcher lineMatcher = pattern.matcher(data.toString()); + while (lineMatcher.find()) { + properties.add(lineMatcher.group(1)); + } + } + + private void parseInOut(StringBuffer data) { + Properties varOrder = new Properties(); + Pattern inLinePattern = Pattern.compile(INPUT); + Matcher inLineMatcher = inLinePattern.matcher(data.toString()); + Integer i = 0; + Integer inLength = 0; + Integer outLength = 0; + if (inLineMatcher.find()) { + Pattern inPattern = Pattern.compile(WORD); + Matcher inMatcher = inPattern.matcher(inLineMatcher.group(1)); + while (inMatcher.find()) { + String var = inMatcher.group(); + if (isContinuous(var)) { + continuous.get(var).setPort("input"); + } + else if (isInteger(var)) { + integers.get(var).setPort("input"); + } + else { + varOrder.setProperty(i.toString(), var); + i++; + inLength++; + } + } + } + Pattern outPattern = Pattern.compile(OUTPUT); + Matcher outLineMatcher = outPattern.matcher(data.toString()); + if (outLineMatcher.find()) { + Pattern output = Pattern.compile(WORD); + Matcher outMatcher = output.matcher(outLineMatcher.group(1)); + while (outMatcher.find()) { + String var = outMatcher.group(); + if (isContinuous(var)) { + continuous.get(var).setPort("output"); + } + else if (isInteger(var)) { + integers.get(var).setPort("output"); + } + else { + varOrder.setProperty(i.toString(), var); + i++; + outLength++; + } + } + } + Pattern internalPattern = Pattern.compile(INTERNAL); + Matcher internalLineMatcher = internalPattern.matcher(data.toString()); + if (internalLineMatcher.find()) { + Pattern internal = Pattern.compile(WORD); + Matcher internalMatcher = internal.matcher(internalLineMatcher.group(1)); + while (internalMatcher.find()) { + String var = internalMatcher.group(); + if (isContinuous(var)) { + continuous.get(var).setPort("internal"); + } + else if (isInteger(var)) { + integers.get(var).setPort("internal"); + } + else { + varOrder.setProperty(i.toString(), var); + i++; + } + } + } + Pattern initState = Pattern.compile(INIT_STATE); + Matcher initMatcher = initState.matcher(data.toString()); + if (initMatcher.find()) { + Pattern initDigit = Pattern.compile("[01X]+"); + Matcher digitMatcher = initDigit.matcher(initMatcher.group()); + digitMatcher.find(); + String[] initArray = new String[digitMatcher.group().length()]; + Pattern bit = Pattern.compile("[01X]"); + Matcher bitMatcher = bit.matcher(digitMatcher.group()); + i = 0; + while (bitMatcher.find()) { + initArray[i] = bitMatcher.group(); + i++; + } + for (i = 0; i < inLength; i++) { + String name = varOrder.getProperty(i.toString()); + if (initArray[i].equals("1")) { + addInput(name, "true"); + } else if (initArray[i].equals("0")) { + addInput(name, "false"); + } else { + addInput(name, "unknown"); + } + } + for (i = inLength; i < inLength + outLength; i++) { + String name = varOrder.getProperty(i.toString()); + if (initArray[i].equals("1") && name != null) { + addOutput(name, "true"); + } else if (initArray[i].equals("0") && name != null) { + addOutput(name, "false"); + } else { + addOutput(name, "unknown"); + } + } + for (i = inLength + outLength; i < initArray.length; i++) { + String name = varOrder.getProperty(i.toString()); + if (initArray[i].equals("1") && name != null) { + addBoolean(name, "true"); + booleans.get(name).setPort("internal"); + } else if (initArray[i].equals("0") && name != null) { + addBoolean(name, "false"); + booleans.get(name).setPort("internal"); + } else { + addBoolean(name, "unknown"); + booleans.get(name).setPort("internal"); + } + } + } else { + if (varOrder.size() != 0) { + System.out.println("WARNING: Boolean variables have not been initialized."); + for (i = 0; i < varOrder.size(); i++) { + if (i < inLength) { + addInput(varOrder.getProperty(i.toString()), "unknown"); + } else { + addOutput(varOrder.getProperty(i.toString()), "unknown"); + } + } + } + } + for (Variable var : continuous.values()) { + if (var.getPort() == null) { + var.setPort("internal"); + } + } + for (Variable var : integers.values()) { + if (var.getPort() == null) { + var.setPort("internal"); + } + } + for (Variable var : booleans.values()) { + if (var.getPort() == null) { + var.setPort("internal"); + } + } + } + + private void parseControlFlow(StringBuffer data) { + allTransitions = null; + Pattern pattern = Pattern.compile(TRANSITION); + Matcher lineMatcher = pattern.matcher(data.toString()); + if (lineMatcher.find()) { + lineMatcher.group(1); + String name = lineMatcher.group(1).replaceAll("\\+/", "P"); + name = name.replaceAll("-/", "M"); + Pattern transPattern = Pattern.compile(WORD); + Matcher transMatcher = transPattern.matcher(name); + while (transMatcher.find()) { + addTransition(transMatcher.group()); + } + } + Pattern placePattern = Pattern.compile(PLACE); + Matcher placeMatcher = placePattern.matcher(data.toString()); + while (placeMatcher.find()) { + String temp = placeMatcher.group(1); + String[] tempPlace = temp.split("\\s"); + for (int i = 0; i < tempPlace.length; i++) { + if (tempPlace[i].contains("+")||tempPlace[i].contains("-")) { + boolean assignment = tempPlace[i].contains("+"); + String var = tempPlace[i].replaceAll("\\+(/\\d+)?", "").replaceAll("-(/\\d+)?", ""); + tempPlace[i] = tempPlace[i].replaceAll("\\+", "P").replaceAll("-", "M"); + tempPlace[i] = tempPlace[i].replace("/",""); + if (getTransition(tempPlace[i])==null) { + addTransition(tempPlace[i]); + Transition trans = getTransition(tempPlace[i]); + trans.addBoolAssign(var, assignment?"TRUE":"FALSE"); + } + } + } + if (isTransition(tempPlace[0]) && isTransition(tempPlace[1])) { + for (int i = 1; i < tempPlace.length; i++) { + String implicitPlace = implicitPlaceMap.get(tempPlace[0]+","+tempPlace[i]); + if (implicitPlace==null) { + implicitPlace = insertPlace(false); + implicitPlaceMap.put(tempPlace[0]+","+tempPlace[i], implicitPlace); + } + addMovement(tempPlace[0],implicitPlace); + addMovement(implicitPlace,tempPlace[i]); + } + } else { + if (isTransition(tempPlace[0])) { + if (!places.containsKey(tempPlace[1])) { + addPlace(tempPlace[1], false); + } + } else { + if (!places.containsKey(tempPlace[0])) { + addPlace(tempPlace[0], false); + } + } + addMovement(tempPlace[0], tempPlace[1]); + } + } + } + + private void parseVars(StringBuffer data) { + Properties initCond = new Properties(); + Properties initValue = new Properties(); + Properties initRate = new Properties(); + Pattern linePattern = Pattern.compile(CONTINUOUS); + Matcher lineMatcher = linePattern.matcher(data.toString()); + if (lineMatcher.find()) { + Pattern varPattern = Pattern.compile(WORD); + Matcher varMatcher = varPattern.matcher(lineMatcher.group(1)); + while (varMatcher.find()) { + addContinuous(varMatcher.group()); + } + Pattern initLinePattern = Pattern.compile(VARS_INIT); + Matcher initLineMatcher = initLinePattern.matcher(data.toString()); + if (initLineMatcher.find()) { + Pattern initPattern = Pattern.compile(INIT_COND); + Matcher initMatcher = initPattern.matcher(initLineMatcher + .group(1)); + while (initMatcher.find()) { + if (continuous.containsKey(initMatcher.group(1))) { + initValue.put(initMatcher.group(1), initMatcher + .group(2)); + } + } + } + Pattern rateLinePattern = Pattern.compile(INIT_RATE); + Matcher rateLineMatcher = rateLinePattern.matcher(data.toString()); + if (rateLineMatcher.find()) { + Pattern ratePattern = Pattern.compile(INIT_COND); + Matcher rateMatcher = ratePattern.matcher(rateLineMatcher + .group(1)); + while (rateMatcher.find()) { + initRate.put(rateMatcher.group(1), rateMatcher.group(2)); + } + } + for (String s : continuous.keySet()) { + if (initValue.containsKey(s)) { + initCond.put("value", initValue.get(s)); + } else { + if (continuous.get(s).getInitValue() != null) // Added this condition for mergeLPN methods sake. SB + initCond.put("value", continuous.get(s).getInitValue()); + else + initCond.put("value", "[-inf,inf]"); + } + if (initRate.containsKey(s)) { + initCond.put("rate", initRate.get(s)); + } else { + if (continuous.get(s).getInitRate() != null) // Added this condition for mergeLPN methods sake. SB + initCond.put("rate", continuous.get(s).getInitRate()); + else + initCond.put("rate", "[-inf,inf]"); + } + addContinuous(s, initCond); + } + } + } + + private void parseIntegers(StringBuffer data) { + String initCond = "0"; + Properties initValue = new Properties(); + Pattern linePattern = Pattern.compile(VARIABLES); + Matcher lineMatcher = linePattern.matcher(data.toString()); + if (lineMatcher.find()) { + Pattern varPattern = Pattern.compile(WORD); + Matcher varMatcher = varPattern.matcher(lineMatcher.group(1)); + while (varMatcher.find()) { + if (!continuous.containsKey(varMatcher.group())) { + addInteger(varMatcher.group(), initCond); + } + } + Pattern initLinePattern = Pattern.compile(VARS_INIT); + Matcher initLineMatcher = initLinePattern.matcher(data.toString()); + if (initLineMatcher.find()) { + Pattern initPattern = Pattern.compile(INIT_COND); + Matcher initMatcher = initPattern.matcher(initLineMatcher + .group(1)); + while (initMatcher.find()) { + if (integers.containsKey(initMatcher.group(1))) { + initValue.put(initMatcher.group(1), initMatcher + .group(2)); + } + } + } + for (String s : integers.keySet()) { + if (initValue.get(s) != null) { + initCond = initValue.get(s).toString(); + } else { + if (integers.get(s).getInitValue() != null) // Added this + // condition for + // mergeLPN + // methods sake. + // SB + initCond = integers.get(s).getInitValue(); + else + initCond = "[-inf,inf]"; + } + addInteger(s, initCond); + } + } + } + + private void parsePlaces(StringBuffer data) { + placeList = null; + Pattern linePattern = Pattern.compile(PLACES_LINE); + Matcher lineMatcher = linePattern.matcher(data.toString()); + if (lineMatcher.find()) { + Pattern markPattern = Pattern.compile(MARKING); + Matcher markMatcher = markPattern.matcher(lineMatcher.group(1)); + while (markMatcher.find()) { + String name = markMatcher.group(); + Place place = new Place(name); + places.put(name, place); + } + } + } + + private void parseMarking(StringBuffer data) { + Pattern linePattern = Pattern.compile(MARKING_LINE); + Matcher lineMatcher = linePattern.matcher(data.toString()); + if (lineMatcher.find()) { + Pattern markPattern = Pattern.compile(MARKING); + Matcher markMatcher = markPattern.matcher(lineMatcher.group(1)); + while (markMatcher.find()) { + String marking = markMatcher.group(); + if (marking.startsWith("<")) { + marking = marking.replace("<", "").replace(">",""); + marking = marking.replace("+", "P").replace("-", "M"); + marking = marking.replaceAll("/", ""); + marking = implicitPlaceMap.get(marking); + } + if (places.get(marking)==null) { + System.out.println("Marking cannot be found: "+marking); + } else { + places.get(marking).setMarking(true); + } + } + } + } + + private boolean parseEnabling(StringBuffer data) { + boolean error = true; + Pattern linePattern = Pattern.compile(ENABLING_LINE); + Matcher lineMatcher = linePattern.matcher(data.toString()); + if (lineMatcher.find()) { + Pattern enabPattern = Pattern.compile(ENABLING); + Matcher enabMatcher = enabPattern.matcher(lineMatcher.group(1)); + while (enabMatcher.find()) { + if (transitions.get(enabMatcher.group(1)).addEnabling( + enabMatcher.group(2)) == false) { + error = false; + } + } + } + return error; + } + + private boolean parseAssign(StringBuffer data, boolean error) { + Pattern linePattern = Pattern.compile(ASSIGNMENT_LINE); + Matcher lineMatcher = linePattern.matcher(data.toString()); + Pattern rangePattern = Pattern.compile(RANGE); + if (lineMatcher.find()) { + Pattern assignPattern = Pattern.compile(ASSIGNMENT); + Matcher assignMatcher = assignPattern.matcher(lineMatcher.group(1) + .replace("\\s", "")); + Pattern varPattern = Pattern.compile(ASSIGN_VAR); + Matcher varMatcher; + while (assignMatcher.find()) { + Transition transition = transitions.get(assignMatcher.group(1)); + varMatcher = varPattern.matcher(assignMatcher.group(2)); + if (varMatcher.find()) { + String variable = varMatcher.group(1); + String assignment = varMatcher.group(2); + if (isInteger(variable)) { + Matcher rangeMatcher = rangePattern.matcher(assignment); + if (rangeMatcher.find()) { + if (rangeMatcher.group(1).matches(INTEGER) + && rangeMatcher.group(2).matches(INTEGER)) { + if (Integer.parseInt(rangeMatcher.group(1)) == Integer + .parseInt(rangeMatcher.group(2))) { + transition.addIntAssign(variable, + rangeMatcher.group(1)); + } + } + if (transition.addIntAssign(variable, "uniform(" + + rangeMatcher.group(1) + "," + + rangeMatcher.group(2) + ")") == false) { + error = false; + } + } else { + if (transition.addIntAssign(variable, assignment) == false) { + error = false; + } + } + } else { + Matcher rangeMatcher = rangePattern.matcher(assignment); + if (rangeMatcher.find()) { + if (rangeMatcher.group(1).matches(INTEGER) + && rangeMatcher.group(2).matches(INTEGER)) { + if (Integer.parseInt(rangeMatcher.group(1)) == Integer + .parseInt(rangeMatcher.group(2))) { + if (transition.addContAssign(variable, + rangeMatcher.group(1)) == false) { + error = false; + } + } + } + if (transition.addContAssign(variable, "uniform(" + + rangeMatcher.group(1) + "," + + rangeMatcher.group(2) + ")") == false) { + error = false; + } + } else if (transition.addContAssign(variable, + assignment) == false) { + error = false; + } + } + } + } + } + return error; + } + + private boolean parseRateAssign(StringBuffer data, boolean error) { + Pattern linePattern = Pattern.compile(RATE_ASSIGNMENT_LINE); + Matcher lineMatcher = linePattern.matcher(data.toString()); + Pattern rangePattern = Pattern.compile(RANGE); + if (lineMatcher.find()) { + Pattern assignPattern = Pattern.compile(ASSIGNMENT); + Matcher assignMatcher = assignPattern.matcher(lineMatcher.group(1) + .replace("\\s", "")); + Pattern varPattern = Pattern.compile(ASSIGN_VAR); + Matcher varMatcher; + while (assignMatcher.find()) { + Transition transition = transitions.get(assignMatcher.group(1)); + varMatcher = varPattern.matcher(assignMatcher.group(2)); + while (varMatcher.find()) { + String variable = varMatcher.group(1); + String assignment = varMatcher.group(2); + Matcher rangeMatcher = rangePattern.matcher(assignment); + if (rangeMatcher.find()) { + if (rangeMatcher.group(1).matches(INTEGER) + && rangeMatcher.group(2).matches(INTEGER)) { + if (Integer.parseInt(rangeMatcher.group(1)) == Integer + .parseInt(rangeMatcher.group(2))) { + if (transition.addRateAssign(variable, + rangeMatcher.group(1)) == false) { + error = false; + } + } + } + if (transition.addRateAssign(variable, "uniform(" + + rangeMatcher.group(1) + "," + + rangeMatcher.group(2) + ")") == false) { + error = false; + } + } else if (transition.addRateAssign(variable, assignment) == false) { + error = false; + } + } + } + } + return error; + } + + private boolean parseDelayAssign(StringBuffer data, boolean error) { + Pattern linePattern = Pattern.compile(DELAY_LINE); + Matcher lineMatcher = linePattern.matcher(data.toString()); + if (lineMatcher.find()) { + Pattern delayPattern = Pattern.compile(DELAY); + Matcher delayMatcher = delayPattern.matcher(lineMatcher.group(1) + .replace("\\s", "")); + while (delayMatcher.find()) { + Transition transition = transitions.get(delayMatcher.group(1)); + Pattern rangePattern = Pattern.compile(RANGE); + Matcher rangeMatcher = rangePattern.matcher(delayMatcher + .group(2)); + String delay; + if (rangeMatcher.find()) { + if (rangeMatcher.group(1).equals(rangeMatcher.group(2))) { + delay = rangeMatcher.group(1); + } else { + delay = "uniform(" + rangeMatcher.group(1) + "," + + rangeMatcher.group(2) + ")"; + } + } else { + delay = delayMatcher.group(2); + } + if (transition.addDelay(delay) == false) { + error = false; + } + } + } + /* + for (Transition t : transitions.values()) { + if (t.getDelay() == null) { + t.addDelay("0"); + } + } + */ + return error; + } + + private boolean parsePriorityAssign(StringBuffer data, boolean error) { + Pattern linePattern = Pattern.compile(PRIORITY_LINE); + Matcher lineMatcher = linePattern.matcher(data.toString()); + if (lineMatcher.find()) { + Pattern priorityPattern = Pattern.compile(PRIORITY); + Matcher priorityMatcher = priorityPattern.matcher(lineMatcher + .group(1).replace("\\s", "")); + while (priorityMatcher.find()) { + Transition transition = transitions.get(priorityMatcher + .group(1)); + String priority = priorityMatcher.group(2); + if (transition.addPriority(priority) == false) { + error = false; + } + } + } + return error; + } + + private boolean parseBooleanAssign(StringBuffer data, boolean error) { + Pattern linePattern = Pattern.compile(BOOLEAN_LINE); + Matcher lineMatcher = linePattern.matcher(data.toString().replace("\\s", "")); + if (lineMatcher.find()) { + Pattern transPattern = Pattern.compile(BOOLEAN_TRANS); + Matcher transMatcher = transPattern.matcher(lineMatcher.group(1) + .replace("\\s", "")); + Pattern assignPattern = Pattern.compile(BOOLEAN_ASSIGN); + while (transMatcher.find()) { + Transition transition = transitions.get(transMatcher.group(1)); + Matcher assignMatcher = assignPattern.matcher(transMatcher + .group(2)); + for (int i = 0; i < booleans.size(); i++) { + while (assignMatcher.find()) { + String variable = assignMatcher.group(1); + String assignment = assignMatcher.group(2); + if (transition.addBoolAssign(variable, assignment) == false) { + error = false; + } + } + } + } + } + return error; + } + + private boolean parseTransitionRate(StringBuffer data, boolean error) { + Pattern linePattern = Pattern.compile(TRANS_RATE_LINE); + Matcher lineMatcher = linePattern.matcher(data.toString()); + if (lineMatcher.find()) { + Pattern delayPattern = Pattern.compile(ENABLING); + Matcher delayMatcher = delayPattern.matcher(lineMatcher.group(1)); + while (delayMatcher.find()) { + Transition transition = transitions.get(delayMatcher.group(1)); + if (transition.addDelay("exponential(" + delayMatcher.group(2) + + ")") == false) { + error = false; + } + } + } + return error; + } + + private void parseFailTransitions(StringBuffer data) { + Pattern linePattern = Pattern.compile(FAIL_LINE); + Matcher lineMatcher = linePattern.matcher(data.toString()); + if (lineMatcher.find()) { + for (String s : lineMatcher.group(1).split("\\s")) { + if (!s.equals("")) { + transitions.get(s).setFail(true); + } + } + } + } + + private void parsePersistentTransitions(StringBuffer data) { + Pattern linePattern = Pattern.compile(PERSISTENT_LINE); + Matcher lineMatcher = linePattern.matcher(data.toString()); + if (lineMatcher.find()) { + for (String s : lineMatcher.group(1).split("\\s")) { + if (!s.equals("")) { + transitions.get(s).setPersistent(true); + } + } + } + } + + /** + * This method extracts the boolean variables associated with inequalities + * involved in the boolean assignments and the enabling conditions on + * transitions. + */ + public void parseBooleanInequalities(){ + /* + * The expression trees for the boolean assignment and the enabling + * conditions are contained in the Transitions. + */ + HashMap inequalities = + new HashMap(); + for(Transition T : transitions.values()){ + // Extract the inequalities from the boolean expression. + for(ExprTree E : T.getBoolAssignTrees().values()){ + parseBooleanInequalities(E, inequalities); + } + + // Extract the inequalities from the enabling condition. + parseBooleanInequalities(T.getEnablingTree(), inequalities, T); + } + + // Add the inequalities to the booleans and variables. + for(InequalityVariable iv : inequalities.keySet()){ + booleans.put("$" + iv.toString(), iv); + variables.add(iv); + } + } + + /** + * Extracts the boolean variables associated with inequalities from a + * single ExprTree. This method is not meant for use with enabling + * conditions since it will not register the transition with the + * inequality variable. + * @param ET + * The expression tree for which the inequalities are extracted. + */ + private void parseBooleanInequalities(ExprTree ET, + HashMap previousInequalities){ + parseBooleanInequalities(ET, previousInequalities, null); + } + + /** + * Extracts the boolean variables associated with inequalities from a + * single ExprTree. + * @param ET + * The expression tree for which the inequalities are extracted. + * @param T + * If this expression tree is from an enabling condition, then the Transition + * whose enabling condition that gave rise to this expression tree. Null + * otherwise. + */ + private void parseBooleanInequalities(ExprTree ET, + HashMap previousInequalities, Transition T){ + /* + * This method servers as a driver method for a recursive like search. + * The basic idea is to explore the tree until an inequality is found, + * create a new variable for the inequality including the subtree rooted + * at that node, and replace the node with a boolean variable. + */ + + // Create a list of operators to match. + String[] operators = new String[]{"<", "<=", ">", ">=", "="}; + + // Get the nodes containing inequalities. + ArrayList inequalities = new ArrayList(); + findInequalityNodes(ET, operators, inequalities); + + parseBooleanInequalities(inequalities, previousInequalities, T); + + } + + /** + * Extracts boolean inequalities at the nodes of relational operators provided. + * @param inequalities + * An ExprTree array containing nodes whose roots are a relational + * operator. + * @param T + * If this expression tree is from an enabling condition, then the Transition + * whose enabling condition that gave rise to this expression tree. Null + * otherwise. + */ + private void + parseBooleanInequalities(ArrayList inequalities, + HashMap previousInequalities, Transition T){ + // For each node, create an InequalityVariable, add it to the set of variables, + // and replace the current node of the ExprTree with the InequaltiyVariable. + +// HashMap variableMap = +// new HashMap(); + + for(ExprTree ET : inequalities){ // ET phone home. + + // Extract the expression for naming the new InequalityVariable. + String booleanName = "$" + ET.toString(); + + // Create the InequalityVariable. + InequalityVariable newVariable = new InequalityVariable(booleanName, "false", + ET.shallowclone(), this); + + // Check if the Variable is present already. + Variable v = booleans.get(booleanName); + + if(v != null){ + // Check if it is an InequalityVariable. + if(!(v instanceof InequalityVariable)){ + throw new IllegalStateException("Name collision. The extracted " + + "name for an InequalityVariable matches a name already " + + "given to a boolean variable."); + } + /* + else{ +// InequalityVariable iv = (InequalityVariable) v; + +// +// Not needed anymore since the list is not dynamically change +// anymore. +// +// iv.increaseCount(); + } + */ + } + else{ + // Register variable with the continuous variable. + // This is taken care of by the constructor. + // TODO : finish. + + // Add the variable + //booleans.put(booleanName, newVariable); + //variables.add(newVariable); + // Check if we have seen this variable before. + InequalityVariable seenBefore = previousInequalities.get(newVariable); + if(seenBefore == null){ + // We have not seen this variable before, so add it to the + // list. + previousInequalities.put(newVariable, newVariable); + if(T != null){ + // If there is a transition, register it. + newVariable.addTransition(T); + } + } + else if(T != null){ + // We've seen this variable before. So no need to add it. Just + // need to register the transition. If the transition is null + // there is nothing to do. + seenBefore.addTransition(T); + } + + } + + // Replace the node into a boolean value. + // The the type. + ET.isit = 'b'; + ET.logical = true; + + // Change the name. + ET.variable = booleanName; + + // Change the op. + ET.op = ""; + + // Remove the branches. + ET.r1 = null; + ET.r2 = null; + } + + //return variableMap; + } + + /** + * Searches an expression tree and finds the nodes that contain an operator. + * @param ET + * The ExprTree to search. + * @param operators + * The operators to find. + * @param nodes + * The list to add the found nodes to. + */ + private void findInequalityNodes(ExprTree ET, String[] operators, + ArrayList nodes){ + + // Check if ET node is null, if so return. (Base case 1 for recursion.) + if(ET == null){ + return; + } + + // Check if ET is a node we want. (Base case 2 for recursion. + // Relations cannot be nested.) + for(int i=0; i otherVarIndexMap = otherLpn.getVarIndexMap(); + String[] interfaceVars = otherLpn.getInterfaceVariables(); + for(int i = 0; i < interfaceVars.length; i++){ + String var = interfaceVars[i]; + Integer thisIndex = this._varIndexMap.getValue(var); + if(thisIndex != null){ + varIndexArrayThisLpn[arrayIndex] = thisIndex; + varIndexArrayOtherLpn[arrayIndex] = otherVarIndexMap.getValue(var); + arrayIndex++; + } + } + } + + private String[] getInterfaceVariables() { + int size = getAllInputs().keySet().size() + getAllOutputs().keySet().size(); + String[] interfaceVariables = new String[size]; + HashSet interfaceSet = new HashSet(); + int i = 0; + for(String input : getAllInputs().keySet()){ + interfaceVariables[i++] = input; + interfaceSet.add(input); + } + for(String output : getAllOutputs().keySet()){ + if(interfaceSet.contains(output)) + continue; + interfaceVariables[i++] = output; + } + return interfaceVariables; + } + + public void setThisIndexList(List indexList){ + this.thisIndexList = indexList; + } + + public void setOtherIndexList(List indexList){ + this.otherIndexList = indexList; + } + + public List getThisIndexList(){ + return this.thisIndexList; + } + + public List getOtherIndexList(){ + return this.otherIndexList; + } + + public int[] getThisIndexArray(int i){ + return this.thisIndexList.get(i); + } + + public int[] getOtherIndexArray(int i){ + return this.otherIndexList.get(i); + } + + private static final String PROPERTY = "#@\\.property ([^@]*)\\n"; + + private static final String INPUT = "\\.inputs([[\\s[^\\n]]\\w+]*?)\\n"; + + private static final String OUTPUT = "\\.outputs([[\\s[^\\n]]\\w+]*?)\\n"; + + private static final String INTERNAL = "\\.internal([[\\s[^\\n]]\\w+]*?)\\n"; + + private static final String INIT_STATE = "#@\\.init_state \\[(\\w*)\\]"; + + private static final String TRANSITION = "\\.dummy([^\\n]*?)\\n"; + + private static final String WORD = "(\\S+)"; + + private static final String INTEGER = "([-\\d]+)"; + + private static final String PLACE = "\\n([\\w_\\+-/&&[^\\.#]]+[ ]+[\\w_\\+-/]+([ ]*[\\w_\\+-/]+)*)"; + //"\\n([\\w_\\+-/&&[^\\.#]]+ [\\w_\\+-/]+)"; + + private static final String CONTINUOUS = "#@\\.continuous ([.[^\\n]]*)\\n"; + + private static final String VARS_INIT = "#@\\.init_vals \\{([\\S[^\\}]]*?)\\}"; + + private static final String INIT_RATE = "#@\\.init_rates \\{([\\S[^\\}]]*?)\\}"; + + private static final String INIT_COND = "<(\\w+)=([\\S^>]*?)>"; + + private static final String VARIABLES = "#@\\.variables ([.[^\\n]]*)\\n"; + + private static final String PLACES_LINE = "#\\|\\.places ([.[^\\n]]*)\\n"; + + private static final String MARKING = "(\\<\\w+[+-](/\\d+)*,\\w+[+-](/\\d+)*\\>)|(\\w+)"; + //"\\w+"; + + private static final String MARKING_LINE = "\\.marking \\{(.*)\\}"; + + private static final String ENABLING_LINE = "#@\\.enablings \\{([.[^\\}]]*?)\\}"; + + private static final String ENABLING = "<([\\S[^=]]+?)=\\[([^\\]]+?)\\]>?"; + + private static final String ASSIGNMENT_LINE = "#@\\.assignments \\{([.[^\\}]]*?)\\}"; + + private static final String RATE_ASSIGNMENT_LINE = "#@\\.rate_assignments \\{([.[^\\}]]*?)\\}"; + + private static final String ASSIGNMENT = "<([\\S[^=]]+?)=\\[(\\S+?)\\]>"; + + private static final String ASSIGN_VAR = "([^:]+?):=(.+)"; + + private static final String DELAY_LINE = "#@\\.delay_assignments \\{([\\S[^\\}]]*?)\\}"; + + private static final String DELAY = "<([\\w_]+)=\\[(\\S+?)\\]>"; + + private static final String RANGE = "\\[([\\w-]+?),([\\w-]+?)\\]"; + + private static final String PRIORITY_LINE = "#@\\.priority_assignments \\{([\\S[^\\}]]*?)\\}"; + + private static final String PRIORITY = "<([\\w_]+)=\\[(\\S+?)\\]>"; + + private static final String TRANS_RATE_LINE = "#@\\.transition_rates \\{([\\S[^\\}]]*?)\\}"; + + private static final String FAIL_LINE = "#@\\.failtrans ([.[^\\n]]*)\\n"; + + private static final String PERSISTENT_LINE = "#@\\.non_disabling ([.[^\\n]]*)\\n"; + + private static final String BOOLEAN_LINE = "#@\\.boolean_assignments \\{([\\S[^\\}]]*?)\\}"; + + private static final String BOOLEAN_TRANS = "<(\\S+?)=\\[(\\S*?)\\]>"; + + private static final String BOOLEAN_ASSIGN = "([^:]+?):=(.+)"; + + @Override + public String toString() { + return "LhpnFile [label=" + label + ", lpnIndex=" + lpnIndex + "]"; + } + + public StateGraph getStateGraph() { + return this.stateGraph; + } + + public void addStateGraph(StateGraph stateGraph) { + if (this.stateGraph == null) + this.stateGraph = stateGraph; + } + + + +} \ No newline at end of file diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Lpn2verilog.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Lpn2verilog.java new file mode 100644 index 000000000..9881bc247 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Lpn2verilog.java @@ -0,0 +1,665 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn; + +import java.io.*; +import java.util.*; + +import edu.utah.ece.async.ibiosim.dataModels.util.GlobalConstants; +import edu.utah.ece.async.ibiosim.dataModels.util.exceptions.BioSimException; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Lpn2verilog { + //String place; + + public static void convert(String lpnFileName) throws BioSimException { + HashMap visitedPlaces; + String enable = ""; + String separator = GlobalConstants.separator; + try{ + LPN lpn = new LPN(); + lpn.load(lpnFileName); + String svFileName = lpnFileName.replaceAll(".lpn", ".sv"); + File svFile = new File(svFileName); + svFile.createNewFile(); + String[] svPath = svFileName.split(separator); + //for (int i=0; i < svPath.length; i++){ + //System.out.println("\nModule string is " + svPath[i] + "\n");} + String svModuleName = svPath[svPath.length -1].split("\\.")[0]; + //System.out.println("\nModule name is " + svModuleName + "\n"); + BufferedWriter sv = new BufferedWriter(new FileWriter(svFile)); + StringBuffer initBuffer = new StringBuffer(); + StringBuffer markedPlaceBuffer = new StringBuffer(); + StringBuffer assertionBuffer = new StringBuffer(); + sv.write("`timescale 1ps/1fs\n\n"); //TODO: THIS IS ASSUMPTION + Boolean first = true; + String[] varsList = lpn.getVariables(); + sv.write("module "+svModuleName + " ("); + for (String v: varsList){ + if (lpn.isOutput(v)){ + if (first){ + if (lpn.isInteger(v) || lpn.isContinuous(v)){ + sv.write("output real " + v); //TODO: Integer if dmv? + } else{ + sv.write("output logic " + v); + } + first = false; + } else{ + if (lpn.isInteger(v) || lpn.isContinuous(v)){ + sv.write(", output real " + v); + } else{ + sv.write(", output logic " + v); + } + } + } + else if (lpn.isInput(v)){ + if (first){ + if (lpn.isInteger(v) || lpn.isContinuous(v)){ + sv.write("input real " + v);//svFileName.split("\\.")[0]+ + } else{ + sv.write("input wire " + v);//svFileName.split("\\.")[0]+ + } + first = false; + } else{ + if (lpn.isInteger(v) || lpn.isContinuous(v)){ + sv.write(", input real " + v); + } else{ + sv.write(", input wire " + v); + } + } + } + //else deal with inout and internal + } + sv.write(");\n"); + first = true; + String[] transitionList = lpn.getTransitionList(); + + ArrayList transArrayList = new ArrayList(Arrays.asList(transitionList)); + //System.out.println("\ntransArray list is " + transArrayList + "\n"); + Collections.sort(transArrayList,new Comparator(){ + @Override + public int compare(String a, String b){ + return(a.compareToIgnoreCase(b)); + } + }); + transArrayList.toArray(transitionList); + String[] placeList = lpn.getPlaceList(); + ArrayList placeArrayList = new ArrayList(Arrays.asList(placeList)); + Collections.sort(placeArrayList,new Comparator(){ + @Override + public int compare(String a, String b){ + return(a.compareToIgnoreCase(b)); + } + }); + placeArrayList.toArray(placeList); + + initBuffer.append("\t\t$dumpfile(\"" + svModuleName + ".vcd\");\n"); + initBuffer.append("\t\t$dumpvars(0," + svModuleName + ");\n"); + for (String st: transitionList){ + if (lpn.getTransition(st).isPersistent()){ + if (first){ + sv.write("\treg " + st+"p"); + first = false; + } else{ + sv.write(", " + st); + } + + //} + if (!first){ + sv.write(";\n"); + } + //} + first = true; + } + } + + first = true; + for (String st: transitionList){ + //if (!lpn.getTransition(st).isPersistent() || lpn.getTransition(st).hasConflictSet()){ + + + if (first){//System.out.println("This is a non- persistent Transition :"+st); + sv.write("\twire " + st); + first = false; + } else{ + sv.write(", " + st); + } + //} + } + if (!first){ + sv.write(";\n"); + } + first = true; + for (String v: varsList){ + if (!lpn.isInput(v) && !lpn.isOutput(v) && !lpn.isContinuous(v)){ + if (first){ + first = false; + sv.write("\treal " + v); + } + else + sv.write("," + v); + } + + else + if (lpn.isContinuous(v)){ + if(first){ + first = false; + sv.write("\treal "+v+", rate_"+v); + } + else sv.write(","+v+", rate_"+v); + } + //else {} + //sv.write("," + v); + } + if (!first) + sv.write(";\n"); + //initBuffer.append(";\n"); + HashMap tag = new HashMap(); + visitedPlaces = new HashMap(); + int netCount = 0; + first = true; + for (String v2: varsList){boolean contiCounter = false; + if(lpn.isContinuous(v2)){ + if (!contiCounter){ + initBuffer.append("\t\t reset = 1; \n"); contiCounter= true; + } + String initRate = lpn.getInitialRate(v2); + initRate = initRate.replace("[","uniform("); + initRate = initRate.replace("]",")"); + //System.out.println("initRate = "+initRate); + initBuffer.append("\t\t rate_"+v2+" = "+initRate+";\n"); + String initValue = lpn.getInitialVal(v2); + initValue = initValue.replace("[","uniform("); + initValue = initValue.replace("]",")"); + initBuffer.append("\t\t"+v2+" ="+initValue+";\n"); + } + else { + String initValue = lpn.getInitialVal(v2); + initValue = initValue.replace("[","uniform("); + initValue = initValue.replace("]",")"); + initBuffer.append("\t\t"+v2+" ="+initValue+";\n"); + } + + + } + for (String st: placeList){ + if (first){ + sv.write("\tlogic " + st); + if (lpn.getPlace(st).isMarked()){ + initBuffer.append("\t\t" + st + " = 0"); + + if (markedPlaceBuffer.length() == 0) + markedPlaceBuffer.append("\t\t#1;\n"); + markedPlaceBuffer.append("\t\t" + st + " = 1; //Initially Marked\n"); + tag = tagNet(lpn,st,netCount,tag,visitedPlaces); + netCount++; + } + else + initBuffer.append("\t\t" + st + " = 0"); + first = false; + } else{ + sv.write(", " + st); + if (lpn.getPlace(st).isMarked()){ + initBuffer.append("; " + st + " = 0"); + if (markedPlaceBuffer.length() == 0) + markedPlaceBuffer.append("\t\t#1;\n"); + markedPlaceBuffer.append("\t\t" + st + " = 1; //Initially Marked\n"); + tagNet(lpn,st,netCount,tag,visitedPlaces); + netCount++; + } + else + initBuffer.append("; " + st + " = 0"); + } + if (lpn.getPreset(st) == null){ + //TODO: traverse all the non-repeating transitions from here and assign a tag to them + } + } + for (String v1: varsList){ + if(lpn.isContinuous(v1)){ + sv.write(", fastClk,reset"); + break; + } + } //new code + if (!first) + sv.write(";\n"); + + if (!first){ + initBuffer.append(";\n"); + initBuffer.append(markedPlaceBuffer); + } + boolean firstCont = true; + for (String v: varsList){ + if ((v != null) && (lpn.isOutput(v))){ //Initialize only outputs. Inputs will be initialized in their driver modules. Null condition Not Required ?? + //String initVal = lpn.getInitialVal(v); + if (lpn.isContinuous(v) || lpn.isInteger(v)){ + if (lpn.isContinuous(v)){ + // TODO: Call Verilog-AMS generation from here. No System Verilog in this case + //double initRate = Double.parseDouble(lpn.getInitialRate(v)); + if (firstCont){ + firstCont = false; + // initBuffer.append("\t\tentryTime<=$time;\n"); + // sv.write("\treal entryTime;\n"); + } + //sv.write("\treal rate_" + v + ", change_" + v + ";\n"); + if ((lpn.getInitialRate(v) != null) && (!lpn.getInitialRate(v).equalsIgnoreCase("unknown"))){ + //String initBufferString = getInitBufferString(v, lpn.getInitialRate(v)); + //initBuffer.append("\t\trate_" + initBufferString); + } + if ((lpn.getInitialVal(v) != null) && (!lpn.getInitialVal(v).equalsIgnoreCase("unknown"))){ + //String initBufferString = getInitBufferString(v, lpn.getInitialVal(v)); + // initBuffer.append("\t\tchange_" + initBufferString); + } + } else { + if ((lpn.getInitialVal(v) != null) && (!lpn.getInitialVal(v).equalsIgnoreCase("unknown"))){ + String initBufferString = getInitBufferString(v, lpn.getInitialVal(v)); + initBuffer.append("\t\t" + initBufferString); + } + } + } + else { // boolean variable + String initValue = lpn.getInitialVal(v); + if (initValue.equals("true")){ + initBuffer.append("\t\t" + v + " = 1'b1;\n"); + } + else if (initValue.equals("false")){ + initBuffer.append("\t\t" + v + " = 1'b0;\n"); + } + else { + //System.out.println("WARNING: The initial value of Boolean variable " + v + " should be a boolean value."); + } + } + } + } + sv.write("\tinitial begin\n"); + sv.write(initBuffer.toString()); + for (String v1: varsList){ + if(lpn.isContinuous(v1)){ + sv.write("\t\treset = 0;\n"); + sv.write("\tend\n\n"); + sv.write("\talways #1 fastClk = (~fastClk)&(~reset); \n\n"); + break; + } + } + for (String v1: varsList){ + if(lpn.isContinuous(v1)){ + sv.write("\talways @(fastClk) begin \n"); + sv.write("\t"+v1+" <="+v1+"+rate_"+v1+";\n"); + sv.write("\tend \n\n"); + //break; + } + } //new code + //sv.write("\tend\n"); + int contiCounter =0 ; + for(String v1 :varsList){ + if (lpn.isContinuous(v1)){ + contiCounter++; + } + } + if (contiCounter ==0) sv.write("\t\t end \n\n"); + + Boolean[] firstTransition = new Boolean[netCount]; + //StringBuffer[] alwaysBuffer = new StringBuffer[netCount]; + // StringBuffer[] prioritiesBuffer = new StringBuffer[netCount]; + StringBuffer[] assignmentsBuffer = new StringBuffer[netCount]; + for (int j = 0; j < netCount; j++){ //System.out.println("Netcount is :"+netCount); + firstTransition[j] = true; + // alwaysBuffer[j] = new StringBuffer(); dec 4,2010 + // prioritiesBuffer[j] = new StringBuffer(); + assignmentsBuffer[j] = new StringBuffer(); + } + for (String st : transitionList){ + if (!lpn.getTransition(st).isPersistent()){ // System.out.println("This is a Non-Peristent transition : "+st); + //if (transitionList.) + sv.write("\tassign "); + ExprTree delayTree = lpn.getTransition(st).getDelayTree(); + //System.out.println("Delay Tree :"+delayTree+"for transition :"+st); + if (delayTree != null){ + String delay = delayTree.getElement("Verilog"); + //System.out.println("Delay "+delay); + if (delay.contains("uniform")){ //range + delay = delay.replaceFirst("uniform\\(", ""); + delay = delay.substring(0, delay.length()-1); //delay = delay.replace("\\)", ""); + } else { + delay = delay + "," + delay; + } + sv.write("#(delay(~" + st + "," + delay + ")) " + st + " = "); + + } else{ + sv.write(st + " = "); + } + if (lpn.getPreset(st).length != 0){ //Assuming there's no transition without a preset. + first = true; + for (String st2 : lpn.getPreset(st)){ //System.out.println("getPreset :"+st2); + if (first){ + sv.write(st2); + first = false; + } + else{ + sv.write(" && " + st2); + } + + } + if (lpn.getEnablingTree(st) != null){ + //System.out.println("enabling"); + sv.write(" && (" + lpn.getEnablingTree(st).getElement("Verilog") + ")"); + //System.out.println(st +" enabling " + lpn.getEnablingTree(st).getElement("Verilog")); + } + } + sv.write(";\n"); + if (lpn.getTransition(st).isFail()){ + assertionBuffer.append("\talways @(" + st + ") begin\n"); + assertionBuffer.append("\t\tassert(!" + st + ")\n"); + assertionBuffer.append("\t\telse\n"); + assertionBuffer.append("\t\t\t$error(\"Error! Assertion " + st + " failed at time %t\",$time);\n\tend\n"); + } else { + + assignmentsBuffer[tag.get(st)].append("\talways @(posedge " + st + ") begin\n"); //dec 4, 2010 + for (String st2 : lpn.getPreset(st)){//System.out.println(" tag.get(st) :"+tag.get(st)); + assignmentsBuffer[tag.get(st)].append("\t\t" + st2 + " <= 0;\n"); + } + for (String st2 : lpn.getPostset(st)){ + assignmentsBuffer[tag.get(st)].append("\t\t" + st2 + " <= 1;\n"); + } + HashMap assignmentTrees = lpn.getTransition(st).getAssignTrees(); + HashMap rateAssignmentTrees = lpn.getTransition(st).getRateAssignTrees(); + HashMap valueAssignmentTrees = lpn.getTransition(st).getIntAssignTrees(); + HashMap contAssignmentTrees = lpn.getTransition(st).getContAssignTrees(); //System.out.println("assignmentTrees.size() :"+assignmentTrees); + if (assignmentTrees.size() != 0){ + for (String st2 : valueAssignmentTrees.keySet()){ + //System.out.println("Assignment " + st2 + " <= " + lpn.getTransition(st).getAssignTree(st2)); + String asgnmt = valueAssignmentTrees.get(st2).getElement("Verilog"); + //System.out.println("asgnmt :"+asgnmt); + if ((asgnmt != null) && (asgnmt != "")) + assignmentsBuffer[tag.get(st)].append("\t\t" + st2 + " <= " + asgnmt + ";\n"); + } + for (String st2 : contAssignmentTrees.keySet()){ + //System.out.println("Assignment " + st2 + " <= " + lpn.getTransition(st).getAssignTree(st2)); + String asgnmt = contAssignmentTrees.get(st2).getElement("Verilog"); + if ((asgnmt != null) && (asgnmt != "")) + assignmentsBuffer[tag.get(st)].append("\t\t" + st2 + " <= " + asgnmt + ";\n"); + } + for (String st2 : rateAssignmentTrees.keySet()){//System.out.println("st2 :"+st2); + //System.out.println("Assignment " + st2 + " <= " + lpn.getTransition(st).getAssignTree(st2)); + String asgnmt = rateAssignmentTrees.get(st2).getElement("Verilog");// System.out.println("asgnmt :"+asgnmt); + if (asgnmt != null){ + //assignmentsBuffer[tag.get(st)].append("\t\tentryTime <= $time;\n"); + assignmentsBuffer[tag.get(st)].append("\t\trate_" + st2 + " <= " + asgnmt + ";\n"); + //assignmentsBuffer[tag.get(st)].append("\t\tchange_" + st2 + " <= " + st2 + ";\n"); + } + } + } + assignmentsBuffer[tag.get(st)].append("\tend\n"); + } + } + else{ + + //if( lpn.getTransition(st).hasConflictSet()){ + //int size = transitionList.length; + //System.out.println("st in conflict:"+st); + //Transition[] trans = new Transition[5]; + //Transition[] conflictSet = new Transition[size]; + //conflictSet = lpn.getTransition(st).getConflictSet(); + //System.out.println("This is the conflict set size :"+size); + + + sv.write("\tassign "); + ExprTree delayTree = lpn.getTransition(st).getDelayTree(); + //System.out.println("Delay Tree :"+delayTree+"for transition :"+st); + if (delayTree != null){ + String delay = delayTree.getElement("Verilog"); + //System.out.println("Delay "+delay); + if (delay.contains("uniform")){ //range + delay = delay.replaceFirst("uniform\\(", ""); + delay = delay.substring(0, delay.length()-1); //delay = delay.replace("\\)", ""); + } else { + delay = delay + "," + delay; + } + sv.write("#(delay(~" + st + "," + delay + ")) " + st + " = "); + + } else{ + sv.write(st + " = "); + } + if (lpn.getPreset(st).length != 0){ //Assuming there's no transition without a preset. + first = true; + for (String st2 : lpn.getPreset(st)){// System.out.println("getPreset :"+st2); + if (first){ + sv.write("("+st2); + first = false; + } + else{ + sv.write(" && " + st2); + } + + } + sv.write(" && " +st+"p)"); + //if (lpn.getEnablingTree(st) != null){ + //System.out.println("enabling"); + //sv.write(" && (" + lpn.getEnablingTree(st).getElement("Verilog") + ")"); + // System.out.println(st +" enabling " + lpn.getEnablingTree(st).getElement("Verilog")); + //} + } + sv.write(";\n");// conflict box ends here + + HashMap assignmentTrees = lpn.getTransition(st).getAssignTrees(); + HashMap rateAssignmentTrees = lpn.getTransition(st).getRateAssignTrees(); + HashMap valueAssignmentTrees = lpn.getTransition(st).getIntAssignTrees(); + HashMap contAssignmentTrees = lpn.getTransition(st).getContAssignTrees(); //System.out.println("assignmentTrees.size() :"+assignmentTrees); + + + if (lpn.getEnablingTree(st) != null){ + enable = lpn.getEnablingTree(st).getElement("Verilog"); + //System.out.println("enabling"); + //sv.write(" && (" + lpn.getEnablingTree(st).getElement("Verilog") + ")"); + //System.out.println(st +" enabling " + enable); + } + + for (String place : lpn.getPreset(st)){ + //System.out.println("getPreset :"+place); + if (enable!=null){ + assignmentsBuffer[tag.get(st)].append("\talways @(posedge ("+ enable + ") && (" +place+")) begin\n");} //dec 4, 2010//dec 4, 2010 + else assignmentsBuffer[tag.get(st)].append("\talways @(posedge " +place+") begin\n"); + } + + //ExprTree delay = lpn.getDelayTree(st); + //System.out.println(" delay....delay :"+delay); + for (String st2 : lpn.getPreset(st)){ + if (lpn.getEnablingTree(st) != null){ + enable = lpn.getEnablingTree(st).getElement("Verilog"); + + + //System.out.println(" tag.get(st) :"+tag.get(st)); + assignmentsBuffer[tag.get(st)].append("\t\t" + st + "p <= (("+enable+") && "+st2+");\n"); + //else assignmentsBuffer[tag.get(st)].append("\t\t" + st + "p <= "+st2+";\n"); + } + else assignmentsBuffer[tag.get(st)].append("\t\t" + st + "p <= "+st2+";\n"); + } + + assignmentsBuffer[tag.get(st)].append("\tend\n"); + + // add 1 more normal always block here for persistent transition. + + if (lpn.getTransition(st).isFail()){ + assertionBuffer.append("\talways @(" + st + ") begin\n"); + assertionBuffer.append("\t\tassert(!" + st + ")\n"); + assertionBuffer.append("\t\telse\n"); + assertionBuffer.append("\t\t\t$error(\"Error! Assertion " + st + " failed at time %t\",$time);\n\tend\n"); + } else { + + assignmentsBuffer[tag.get(st)].append("\talways @(posedge " + st + ") begin\n"); //dec 4, 2010 + for (String st2 : lpn.getPreset(st)){//System.out.println(" tag.get(st) :"+tag.get(st)); + assignmentsBuffer[tag.get(st)].append("\t\t" + st2 + " <= 0;\n"); + } + for (String st2 : lpn.getPostset(st)){ + assignmentsBuffer[tag.get(st)].append("\t\t" + st2 + " <= 1;\n"); + } + //HashMap assignmentTrees = lpn.getTransition(st).getAssignTrees(); + //HashMap rateAssignmentTrees = lpn.getTransition(st).getRateAssignTrees(); + //HashMap valueAssignmentTrees = lpn.getTransition(st).getIntAssignTrees(); + //HashMap contAssignmentTrees = lpn.getTransition(st).getContAssignTrees(); System.out.println("assignmentTrees.size() :"+assignmentTrees); + if (assignmentTrees.size() != 0){ + for (String st2 : valueAssignmentTrees.keySet()){ + //System.out.println("Assignment " + st2 + " <= " + lpn.getTransition(st).getAssignTree(st2)); + String asgnmt = valueAssignmentTrees.get(st2).getElement("Verilog"); + //System.out.println("asgnmt :"+asgnmt); + if ((asgnmt != null) && (asgnmt != "")) + assignmentsBuffer[tag.get(st)].append("\t\t" + st2 + " <= " + asgnmt + ";\n"); + } + for (String st2 : contAssignmentTrees.keySet()){ + //System.out.println("Assignment " + st2 + " <= " + lpn.getTransition(st).getAssignTree(st2)); + String asgnmt = contAssignmentTrees.get(st2).getElement("Verilog"); + if ((asgnmt != null) && (asgnmt != "")) + assignmentsBuffer[tag.get(st)].append("\t\t" + st2 + " <= " + asgnmt + ";\n"); + } + for (String st2 : rateAssignmentTrees.keySet()){//System.out.println("st2 :"+st2); + //System.out.println("Assignment " + st2 + " <= " + lpn.getTransition(st).getAssignTree(st2)); + String asgnmt = rateAssignmentTrees.get(st2).getElement("Verilog"); //System.out.println("asgnmt :"+asgnmt); + if (asgnmt != null){ + assignmentsBuffer[tag.get(st)].append("\t\tentryTime <= $time;\n"); + assignmentsBuffer[tag.get(st)].append("\t\trate_" + st2 + " <= " + asgnmt + ";\n"); + assignmentsBuffer[tag.get(st)].append("\t\tchange_" + st2 + " <= " + st2 + ";\n"); + } + } + } + assignmentsBuffer[tag.get(st)].append("\tend\n"); + } + //} + + } + } + if (transitionList.length > 0){ + if (assertionBuffer.length()!= 0){ + sv.write(assertionBuffer.toString()); + } + for (int j = 0; j < netCount; j++){ + // if ((alwaysBuffer[j] != null) && (alwaysBuffer[j].length() != 0)){ //dec 4,2010 + if ((assignmentsBuffer[j] != null) && (assignmentsBuffer[j].length() != 0)){ //dec 4,2010 + // alwaysBuffer[j].append(") begin\n"); // dec 4,2010 + // sv.write(alwaysBuffer[j].toString()); // dec 4,2010 + // sv.write(prioritiesBuffer[j].toString()); + // sv.write("\t\tprMax" + j + " = pr" + j + ".max[0];\n"); + // sv.write("\t\tif (prMax" + j + " == 0)\n\t\t\tprMax" + j + "=1;\n"); + sv.write(assignmentsBuffer[j].toString()); + // sv.write("\tend\n"); //dec 4,2010 + } + } + } + sv.write("\tfunction real uniform(int a, int b);\n"); + sv.write("\t\treal c;\n"); + sv.write("\t\tif (a==b)\n"); + sv.write("\t\t\treturn a;\n"); + sv.write("\t\tif ((a>0)&&(b>0))\n"); + sv.write("\t\t\tc = $urandom_range(a*1000,b*1000)/1000.0;\n"); + sv.write("\t\telse\n"); + sv.write("\t\t\tc = a+$urandom_range(b*1000-a*1000)/1000.0;\n"); + sv.write("\t\treturn c;\n"); + sv.write("\tendfunction\n"); + sv.write("\tfunction real delay(bit tb, int l, int u);\n"); + sv.write("\t\tif (~tb)\n\t\t\treturn 0.0;\n"); + sv.write("\t\telse if (l == u)\n\t\t\treturn (u + 0.001*$urandom_range(1,100));\n"); + sv.write("\t\telse return(uniform(l,u) + 0.001*$urandom_range(1,100));\n"); + sv.write("\tendfunction\n"); + sv.write("endmodule"); + sv.close(); + //} + } catch (IOException e){ + e.printStackTrace(); + //System.out.println("ERROR: Verilog file could not be created/written."); + } + } + + private static String getInitBufferString(String v, String initValue) { + // Assign initial values/rates to continuous, discrete and boolean variables + // As per translator.java: Extract the lower and upper bounds and set the initial value to the mean. + // Anything that involves infinity, take either the lower or upper bound which is not infinity. + // If both are infinity, set to 0. + + String initBufferString = null; + String tmp_initValue = initValue; + String[] subString = initValue.split(","); + String lowerBound = "0"; + String upperBound = "inf"; + if (tmp_initValue.contains(",")){ + tmp_initValue = tmp_initValue.replaceFirst(",", ""); + for (int i = 0; i 0) + initBufferString = v + " = " + lowerBound + " + $signed((($unsigned($random))%(" + upperBound + "-" + lowerBound + "+1)));\n"; + else if (Double.valueOf(lowerBound) < 0) + initBufferString = v + " = " + lowerBound + " + $signed((($unsigned($random))%(" + upperBound + "+" + Math.abs(Integer.valueOf(lowerBound)) + "+1)));\n"; + else + initBufferString = v + " = " + lowerBound + " + $signed((($unsigned($random))%(" + upperBound + "+1)));\n"; + } + else + initBufferString = v + " = " + lowerBound + ";\n"; + } + } + else { // initial rate is a single number + initBufferString = v + " = " + initValue + ";\n"; + } + return(initBufferString); + } + + private static HashMap tagNet(LPN g, String place, int id, HashMap tag, + HashMap visitedPlaces){ + //System.out.println("Place is :"+place); + if (!visitedPlaces.containsKey(place)){ + visitedPlaces.put(place,true); + for (String postsetTrans : g.getPostset(place)){ + //System.out.println("postset : "+postsetTrans); + tag.put(postsetTrans, id); + //System.out.println("Tagged transition " + postsetTrans + " with " + id); + for (String postsetPlace : g.getPostset(postsetTrans)){// System.out.println("postsetPlace :"+postsetPlace); + tag = tagNet(g, postsetPlace, id, tag, visitedPlaces); + } + } + } + //System.out.println("Hello"); + return tag; + } +} \ No newline at end of file diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/Component.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/Component.java new file mode 100644 index 000000000..820a5c35b --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/Component.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn.LpnDecomposition; + +import java.util.ArrayList; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Place; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.lpn.Variable; +import edu.utah.ece.async.lema.verification.platu.main.Options; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Component extends LPN{ + private ArrayList processIDList; + private ArrayList compTrans; + private ArrayList compPlaces; + private ArrayList compInputs; + private ArrayList compOutputs; + private ArrayList compInternals; + private int compid; + + public Component(LpnProcess process) { + compTrans = new ArrayList(); + compPlaces = new ArrayList(); + processIDList = new ArrayList(); + compInputs = new ArrayList(); + compOutputs = new ArrayList(); + compInternals = new ArrayList(); + + processIDList.add(process.getProcessId()); + compTrans.addAll(process.getProcessTransitions()); + compPlaces.addAll(process.getProcessPlaces()); + compInputs.addAll(process.getProcessInput()); + compOutputs.addAll(process.getProcessOutput()); + compInternals.addAll(process.getProcessInternal()); + compid = process.getProcessId(); + } + + public Component() { + compTrans = new ArrayList(); + compPlaces = new ArrayList(); + processIDList = new ArrayList(); + compInputs = new ArrayList(); + compOutputs = new ArrayList(); + compInternals = new ArrayList(); + } + + public Component getComponent() { + return this; + } + + public Integer getComponentId() { + return compid; + } + + public void setComponentId(Integer id) { + this.compid = id; + } + + public ArrayList getProcessIDList() { + return processIDList; + } + + public void setProcessIDList(ArrayList processIDList) { + this.processIDList = processIDList; + } + + public ArrayList getInternals() { + return compInternals; + } + + public ArrayList getOutputs() { + return compOutputs; + } + + public ArrayList getInputs() { + return compInputs; + } + + public LPN buildLPN(LPN lpnComp) { + // Places + for (int i=0; i< this.getComponentPlaces().size(); i++) { + Place p = this.getComponentPlaces().get(i); + lpnComp.addPlace(p.getName(), p.isMarked()); + } + // Transitions + for (int i=0; i< this.getCompTransitions().size(); i++) { + Transition t = this.getCompTransitions().get(i); + t.setIndex(i); + lpnComp.addTransition(t); + } + // Inputs + for (int i=0; i< this.getInputs().size(); i++) { + Variable var = this.getInputs().get(i); + lpnComp.addInput(var.getName(), var.getType(), var.getInitValue()); + } + // Outputs + for (int i=0; i< this.getOutputs().size(); i++) { + Variable var = this.getOutputs().get(i); + lpnComp.addOutput(var.getName(), var.getType(), var.getInitValue()); + } + // Internal + for (int i=0; i< this.getInternals().size(); i++) { + Variable var = this.getInternals().get(i); + lpnComp.addInternal(var.getName(), var.getType(), var.getInitValue()); + } + return lpnComp; + } + + public ArrayList getCompTransitions() { + return compTrans; + } + + public ArrayList getComponentPlaces() { + return compPlaces; + } + + public int getNumVars() { + // return the number of variables in this component + if (Options.getDebugMode()) { + System.out.println("+++++++ Vars in component " + this.getComponentId() + "+++++++"); + System.out.println("compInputs:"); + for (int i=0; i < compInputs.size(); i++) { + System.out.println(compInputs.get(i).getName()); + } + System.out.println("compOutputs:"); + for (int i=0; i < compOutputs.size(); i++) { + System.out.println(compOutputs.get(i).getName()); + } + System.out.println("compInternal:"); + for (int i=0; i < compInternals.size(); i++) { + System.out.println(compInternals.get(i).getName()); + } + System.out.println("++++++++++++++++++"); + } + return compInputs.size() + compInternals.size() + compOutputs.size(); + } + + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/Edge.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/Edge.java new file mode 100644 index 000000000..21758c8bb --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/Edge.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn.LpnDecomposition; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Edge { + public final Vertex target; + private Integer weight; + + public Edge(Vertex target) { + this.target = target; + this.weight = 0; + } + + public void addWeight() { + this.weight ++ ; + } + + public Integer getWeight() { + return this.weight; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/LpnComponentGraph.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/LpnComponentGraph.java new file mode 100644 index 000000000..b821ec14f --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/LpnComponentGraph.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn.LpnDecomposition; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.PriorityQueue; + +import edu.utah.ece.async.lema.verification.lpn.Variable; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class LpnComponentGraph{ + private Integer maxNumVarsInOneComp; + private HashMap vertices; + public LpnComponentGraph( + HashMap> sharedCompVarsMap, + HashMap compMap, Integer maxNumProcInOneComp) { + this.maxNumVarsInOneComp = maxNumProcInOneComp; + vertices = new HashMap(); + // Create a component graph. vertex = component ID. edge weights = the number of shared variables between two components. + if (sharedCompVarsMap.isEmpty() && compMap.size() == 1) { + for (Iterator compMapIter = compMap.keySet().iterator(); compMapIter.hasNext();) { + Integer curCompId = compMapIter.next(); + Vertex curVertex = new Vertex(compMap.get(curCompId).getComponentId(), maxNumProcInOneComp); + vertices.put(compMap.get(curCompId).getComponentId(), curVertex); + } + } + else { + for (ArrayList componentIDList : sharedCompVarsMap.values()) { + for (int i=0; i edges = curVertex.getAdjacencies(); + // edges != null + Edge e; + if (!edges.keySet().contains(nextVertex.componentID)) { + e = new Edge(nextVertex); + e.addWeight(); + edges.put(nextVertex.componentID, e); + } + else { + e = edges.get(nextVertex.componentID); + e.addWeight(); + } + } + } + } + } + } + } + + } + + public void outputDotFile(String fileName) { + try { + BufferedWriter out = new BufferedWriter(new FileWriter(fileName)); + out.write("digraph G {\n"); + for (Vertex v : vertices.values()) { + String vertexId = v.componentID.toString(); + out.write(vertexId + "[shape=\"ellipse\"" + "]\n"); + for (Edge e : v.getAdjacencies().values()) { + String targetVertexId = e.target.componentID.toString(); + out.write( vertexId + " -> " + targetVertexId + " [label=\"" + e.getWeight() + "\"]\n"); + } + } + out.write("}"); + out.close(); + } + catch (Exception e) { + e.printStackTrace(); + System.err.println("Error outputting state graph as dot file."); + } + } + + public Vertex selectVerticesToCoalesce() { + VertexComparator comparator = new VertexComparator(maxNumVarsInOneComp); + if (vertices.size() < 1) { + return null; + } + PriorityQueue vertexQueue = new PriorityQueue(vertices.size(),comparator); + for (Vertex vertex : vertices.values()) { + //System.out.println("adding vertex " + vertex.componentID); + vertexQueue.add(vertex); + } +// printVertexQueue(vertexQueue); + Vertex destVertex = vertexQueue.poll(); // vertexToMerge and its most connected neighbor will be coalesced into one component. + if (destVertex.getBestNetGain() < 0) + return null; + return destVertex; + } + + @SuppressWarnings("unused") + private static void printVertexQueue(PriorityQueue vertexQueue) { + System.out.println("%%%%%%%%%% vertex queue %%%%%%%%%%%"); + int i = 0; + for (Iterator vertexQueueIter = vertexQueue.iterator(); vertexQueueIter.hasNext();) { + Vertex v = vertexQueueIter.next(); + System.out.println(i + " (" + v.componentID + " <- " + v.getMostConnectedNeighbor().componentID + ")" + " best net gain: " + v.getBestNetGain()); + i++; + } + System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"); + } + + + + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/LpnComponentList.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/LpnComponentList.java new file mode 100644 index 000000000..a6f58eecf --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/LpnComponentList.java @@ -0,0 +1,271 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn.LpnDecomposition; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Random; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Place; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.lpn.Variable; +import edu.utah.ece.async.lema.verification.platu.main.Options; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class LpnComponentList extends LPN{ + private Integer maxNumVarsInOneComp; + private HashMap compMap; // + private HashMap> sharedCompVarsMap; + + public LpnComponentList(Integer maxNumProcInOneComp) { + compMap = new HashMap(); + sharedCompVarsMap = new HashMap>(); + this.maxNumVarsInOneComp = maxNumProcInOneComp; + } + + public void buildComponents(HashMap processMap, String directory, String lpnFileName) { + HashMap> sharedProcessVarsMap = new HashMap>(); + Object[] allProcesses = processMap.values().toArray(); + for (int i=0; i procArray = new ArrayList(2); + procArray.add(curProcess); + procArray.add(nextProcess); + sharedProcessVarsMap.put(curInput, procArray); + } + else { + if (!sharedProcessVarsMap.get(curInput).contains(curProcess)) + sharedProcessVarsMap.get(curInput).add(curProcess); + if (!sharedProcessVarsMap.get(curInput).contains(nextProcess)) + sharedProcessVarsMap.get(curInput).add(nextProcess); + } + } + } + for (int k=0; k procArray = new ArrayList(2); + procArray.add(curProcess); + procArray.add(nextProcess); + sharedProcessVarsMap.put(curOutput, procArray); + } + else { + if (!sharedProcessVarsMap.get(curOutput).contains(curProcess)) + sharedProcessVarsMap.get(curOutput).add(curProcess); + if (!sharedProcessVarsMap.get(curOutput).contains(nextProcess)) + sharedProcessVarsMap.get(curOutput).add(nextProcess); + } + } + } + } + } + if (Options.getDebugMode()) { + printSharedProcessVarMap(sharedProcessVarsMap); + printProcessMap(processMap); + } + // Use wrappers to convert processMap to compMap, and sharedProcessVarsMap to sharedCompMap + for (Integer procID : processMap.keySet()) { + Component comp = new Component(processMap.get(procID)); + compMap.put(comp.getComponentId(), comp); + } + for (Variable v : sharedProcessVarsMap.keySet()) { + ArrayList compIDList = new ArrayList(); + for (LpnProcess proc : sharedProcessVarsMap.get(v)) { + compIDList.add(proc.getProcessId()); + } + sharedCompVarsMap.put(v, compIDList); + } + boolean quitCoalesing = false; + int iter = 0; + while (!quitCoalesing) { + if (Options.getDebugMode()) + printNumProcesses(); + LpnComponentGraph componentGraph = new LpnComponentGraph(sharedCompVarsMap, compMap, maxNumVarsInOneComp); + if (Options.getDebugMode()) { + String graphFileName = lpnFileName + maxNumVarsInOneComp + "Vars" + "_compGraph" + iter + ".dot"; + componentGraph.outputDotFile(directory + separator + graphFileName); + } + Vertex vertexToCoalesce = componentGraph.selectVerticesToCoalesce(); + if (vertexToCoalesce != null) { + Component comp1 = compMap.get(vertexToCoalesce.componentID); + Component comp2 = compMap.get(vertexToCoalesce.getMostConnectedNeighbor().componentID); + if (Options.getDebugMode()) { + System.out.println("*****Coalescing results*******"); + System.out.println("vertices to coalesce: " + vertexToCoalesce.componentID + ", " + vertexToCoalesce.getMostConnectedNeighbor().componentID); + System.out.println("best net gain = " + vertexToCoalesce.getBestNetGain()); + System.out.println("**********************"); + } + coalesceComponents(comp1, comp2); + } + else { + if (Options.getDebugMode()) + System.out.println("No net gain of coalescing components."); + quitCoalesing = true; + } + iter++; + } + } + + private void printNumProcesses() { + System.out.println("************ processes in each componenet ***********"); + for (Component c : compMap.values()) { + System.out.println(c.getComponentId() + " = " + c.getProcessIDList()); + } + System.out.println("*****************************************************"); + } + + private static void printProcessMap(HashMap processMap) { + System.out.println("~~~~~~~~~~~~process map~~~~~~~~~~~~~~"); + for (Iterator processMapIter = processMap.keySet().iterator(); processMapIter.hasNext();) { + Integer procID = processMapIter.next(); + System.out.println("process " + procID + " = " + processMap.get(procID).getProcessId()); + } + } + + private void printComponentMap() { + System.out.println("~~~~~~~~~~~~component map~~~~~~~~~~~~~~"); + for (Iterator processMapIter = compMap.keySet().iterator(); processMapIter.hasNext();) { + Integer procID = processMapIter.next(); + System.out.println("component " + procID + " = " + compMap.get(procID).getComponentId()); + } + } + + public void coalesceComponents(Component comp1, Component comp2) { + // coalesce 2 components, each including one process + Component coalescedComp = new Component(); + // Create the newly coalesced component's processes, inputs, outputs, internals, and component ID. + coalescedComp.setProcessIDList(comp1.getProcessIDList()); + coalescedComp.getProcessIDList().addAll(comp2.getProcessIDList()); + Integer coalescedCompId; + do { + Random rand = new Random(); + coalescedCompId = rand.nextInt(2000); + } while (compMap.keySet().contains(coalescedCompId)); + coalescedComp.setComponentId(coalescedCompId); + ArrayList coalescedInternals = coalescedComp.getInternals(); + ArrayList coalescedOutputs = coalescedComp.getOutputs(); + ArrayList coalescedInputs = coalescedComp.getInputs(); + ArrayList sharedVariables = getSharedVariables(comp1, comp2); + ArrayList coalescedPlaces = coalescedComp.getComponentPlaces(); + ArrayList coalescedTrans = coalescedComp.getCompTransitions(); + comp1.getInputs().removeAll(sharedVariables); + comp2.getInputs().removeAll(sharedVariables); + comp1.getOutputs().removeAll(sharedVariables); + comp2.getOutputs().removeAll(sharedVariables); + coalescedInternals.addAll(sharedVariables); + coalescedInternals.addAll(comp1.getInternals()); + coalescedInternals.addAll(comp2.getInternals()); + coalescedInputs.addAll(comp1.getInputs()); + coalescedInputs.addAll(comp2.getInputs()); + coalescedOutputs.addAll(comp1.getOutputs()); + coalescedOutputs.addAll(comp2.getOutputs()); + coalescedPlaces.addAll(comp1.getComponentPlaces()); + coalescedPlaces.addAll(comp2.getComponentPlaces()); + coalescedTrans.addAll(comp1.getCompTransitions()); + coalescedTrans.addAll(comp2.getCompTransitions()); + + // Update sharedCompVarsMap + for (Variable sharedVar : sharedCompVarsMap.keySet()) { + if (sharedCompVarsMap.get(sharedVar).contains(comp1.getComponentId())) { + sharedCompVarsMap.get(sharedVar).remove(comp1.getComponentId()); + if (!sharedCompVarsMap.get(sharedVar).contains(coalescedComp.getComponentId())) + sharedCompVarsMap.get(sharedVar).add(coalescedComp.getComponentId()); + } + + if (sharedCompVarsMap.get(sharedVar).contains(comp2.getComponentId())) { + sharedCompVarsMap.get(sharedVar).remove(comp2.getComponentId()); + if (!sharedCompVarsMap.get(sharedVar).contains(coalescedComp.getComponentId())) + sharedCompVarsMap.get(sharedVar).add(coalescedComp.getComponentId()); + } + } + for (Variable v : sharedVariables) { + sharedCompVarsMap.remove(v); + } + + if (Options.getDebugMode()) + printSharedCompVarMap(); + // Update the compMap: remove the merged components and add the resultant component + compMap.remove(comp1.getComponentId()); + compMap.remove(comp2.getComponentId()); + compMap.put(coalescedComp.getComponentId(), coalescedComp); + if (Options.getDebugMode()) + printComponentMap(); + } + + private ArrayList getSharedVariables(Component comp1, + Component comp2) { + ArrayList sharedVars = new ArrayList(); + for (Variable v : sharedCompVarsMap.keySet()) { + ArrayList compIDs = sharedCompVarsMap.get(v); + if (compIDs.contains(comp1.getComponentId()) && compIDs.contains(comp2.getComponentId())) + sharedVars.add(v); + } + return sharedVars; + } + + private static void printSharedProcessVarMap( + HashMap> sharedVarMap) { + System.out.println("~~~~~~ shared variables map ~~~~~~~~~~~"); + for (Iterator sharedVarMapIter = sharedVarMap.keySet().iterator(); sharedVarMapIter.hasNext();) { + Variable curSharedVarMap = sharedVarMapIter.next(); + System.out.print(curSharedVarMap + "\t"); + ArrayList map = sharedVarMap.get(curSharedVarMap); + for (int i=0; i sharedVarMapIter = sharedCompVarsMap.keySet().iterator(); sharedVarMapIter.hasNext();) { + Variable curSharedVarMap = sharedVarMapIter.next(); + System.out.print(curSharedVarMap + "\t"); + ArrayList map = sharedCompVarsMap.get(curSharedVarMap); + for (int i=0; i getComponentMap() { + return compMap; + } + + public HashMap> getSharedCompVarsMap() { + return sharedCompVarsMap; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/LpnProcess.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/LpnProcess.java new file mode 100644 index 000000000..3f334ce1f --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/LpnProcess.java @@ -0,0 +1,382 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn.LpnDecomposition; + +import java.util.ArrayList; +import java.util.Iterator; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Place; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.lpn.Variable; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class LpnProcess extends LPN { + + private ArrayList processTrans = new ArrayList(); + private ArrayList processPlaces = new ArrayList(); + private ArrayList processInput = new ArrayList(); + private ArrayList processOutput = new ArrayList(); + private ArrayList processInternal = new ArrayList(); + private int id; + private boolean isStateMachine; + + public LpnProcess(Integer procId) { + id = procId; + isStateMachine = true; + } + + public int getProcessId() { + return id; + } + + public void addTranToProcess(Transition curTran) { + processTrans.add(curTran); + } + + public void addPlaceToProcess(Place curPlace) { + processPlaces.add(curPlace); + } + +// /** +// * This method assigns at least one sticky transition to each process. Transitions whose preset places are marked are considered to be sticky +// * for each process. The purpose of assigning sticky transitions is to break all cycles in each process. In general, one sticky transition is +// * sufficient to break the cycle. However, Floyd's all-pairs shortest-path algorithm (binary) is used to find additional transition(s) that can +// * help to cut the cycle(s). +// */ +// @SuppressWarnings("unchecked") +// public void assignStickyTransitions() { +// // Assign transition(s) with marked post to be sticky +// for (Place p : processPlaces) { +// if (p.isMarked()) { +// if (p.getPreset() != null && p.getPreset().length > 0) { +// Transition[] transitions = p.getPreset(); +// for (int i=0; i processTransCopy = (ArrayList) processTrans.clone(); +// ArrayList transToRemove = new ArrayList(); +// DualHashMap tranIndexInMatrixMap = new DualHashMap(); +// int index = -1; +// for (Iterator processTransCopyIter = processTransCopy.iterator(); processTransCopyIter.hasNext();) { +// Transition curTran = processTransCopyIter.next(); +// if (curTran.isSticky() || curTran.getName().contains("_dummy")) { +// transToRemove.add(curTran); +// continue; +// } +// index++; +// tranIndexInMatrixMap.put(curTran, index); +// } +// processTransCopy.removeAll(transToRemove); +// // Floyd's all-pairs shortest path +// ArrayList> matrix = new ArrayList>(); +// Integer numCycles = 0; +// do { +// if (processTransCopy.size() == 0) { +// continue; +// } +// ArrayList row = new ArrayList(); +// for (int i=0; i) row.clone()); +// row.clear(); +// } +// // find the next reachable transition(s) from the current transition +// for (int i=0; i tranWithBiggestPreset.getPreset().length) { +// tranWithBiggestPreset = tranIndexInMatrixMap.getKey(i); +// } +// } +// } +// tranWithBiggestPreset.setSticky(true); +// // Remove the sticky transition in the matrix. +// Integer tranWithBiggestPresetIndex = tranIndexInMatrixMap.getValue(tranWithBiggestPreset); +// processTransCopy.remove(tranWithBiggestPreset); +// for (int i=0; i 0 && processTransCopy.size() > 0); +// } + +// public void printProcWithStickyTrans() { +// System.out.println("*******Sticky Transitions*******"); +// System.out.println("Process ID:" + this.getProcessId()); +// for (int i=0; i < this.processTrans.size(); i++) { +// if (processTrans.get(i).isSticky()) { +// System.out.println(processTrans.get(i).getName() + " " + processTrans.get(i).getIndex()); +// } +// } +// System.out.println("********************"); +// } +// /** +// * This method assigns at least one sticky transition to each process. Transitions whose preset places are marked are considered to be sticky +// * for each process. The purpose of assigning sticky transitions is to break all cycles in each process. In general, one sticky transition is +// * sufficient to break the cycle. However, Floyd�s all-pairs shortest-path algorithm (binary) is used to find additional transition(s) that can +// * help to cut the cycle(s). +// */ +// @SuppressWarnings("unchecked") +// public void assignStickyTransitions() { +// // Assign transition(s) with marked post to be sticky +// for (Place p : processPlaces) { +// if (p.isMarked()) { +// if (p.getPreset() != null && p.getPreset().length > 0) { +// Transition[] transitions = p.getPreset(); +// for (int i=0; i processTransCopy = (ArrayList) processTrans.clone(); +// ArrayList transToRemove = new ArrayList(); +// DualHashMap tranIndexInMatrixMap = new DualHashMap(); +// int index = -1; +// for (Iterator processTransCopyIter = processTransCopy.iterator(); processTransCopyIter.hasNext();) { +// Transition curTran = processTransCopyIter.next(); +// if (curTran.isSticky() || curTran.getName().contains("_dummy")) { +// transToRemove.add(curTran); +// continue; +// } +// index++; +// tranIndexInMatrixMap.put(curTran, index); +// } +// processTransCopy.removeAll(transToRemove); +// // Floyd's all-pairs shortest path +// ArrayList> matrix = new ArrayList>(); +// Integer numCycles = 0; +// do { +// if (processTransCopy.size() == 0) { +// continue; +// } +// ArrayList row = new ArrayList(); +// for (int i=0; i) row.clone()); +// row.clear(); +// } +// // find the next reachable transition(s) from the current transition +// for (int i=0; i tranWithBiggestPreset.getPreset().length) { +// tranWithBiggestPreset = tranIndexInMatrixMap.getKey(i); +// } +// } +// } +// tranWithBiggestPreset.setSticky(true); +// // Remove the sticky transition in the matrix. +// Integer tranWithBiggestPresetIndex = tranIndexInMatrixMap.getValue(tranWithBiggestPreset); +// processTransCopy.remove(tranWithBiggestPreset); +// for (int i=0; i 0 && processTransCopy.size() > 0); +// } + + + public void print() { + System.out.print("Process ID: " + this.getProcessId() + "\n"); + ArrayList trans = this.getProcessTransitions(); + System.out.println("Transitions:"); + for (Iterator transIter = trans.iterator(); transIter.hasNext();) { + System.out.print(transIter.next() + " "); + } + System.out.print("\n"); + System.out.println("Places:"); + ArrayList places = this.getProcessPlaces(); + for (Iterator placesIter = places.iterator(); placesIter.hasNext();) { + System.out.print(placesIter.next() + " "); + } + System.out.print("\n"); + System.out.println("Inputs:"); + ArrayList input = this.getProcessInput(); + for (Iterator inputIter = input.iterator(); inputIter.hasNext();) { + System.out.println(inputIter.next() + " "); + } + System.out.print("\n"); + System.out.println("Outputs:"); + ArrayList output = this.getProcessOutput(); + for (Iterator outputIter = output.iterator(); outputIter.hasNext();) { + System.out.println(outputIter.next() + " "); + } + System.out.print("\n"); + System.out.println("Internals:"); + ArrayList internal = this.getProcessInternal(); + for (Iterator internalIter = internal.iterator(); internalIter.hasNext();) { + System.out.println(internalIter.next() + " "); + } + System.out.print("\n"); + System.out.println("----------------------------"); + } + + public ArrayList getProcessPlaces() { + return processPlaces; + } + + public ArrayList getProcessTransitions() { + return processTrans; + } + + public ArrayList getProcessInput() { + return processInput; + } + + public ArrayList getProcessOutput() { + return processOutput; + } + + public ArrayList getProcessInternal() { + return processInternal; + } + + public ArrayList getProcessVariables() { + ArrayList variables = new ArrayList(); + variables.addAll(processInput); + variables.addAll(processOutput); + variables.addAll(processInternal); + return variables; + } + + public int getProcessVarSize() { + return processInternal.size() + processInput.size() + processOutput.size(); + } + + public LPN buildLPN(LPN lpnProc) { + // Places + for (int i=0; i< this.getProcessPlaces().size(); i++) { + Place p = this.getProcessPlaces().get(i); + lpnProc.addPlace(p.getName(), p.isMarked()); + } + // Transitions + for (int i=0; i< this.getProcessTransitions().size(); i++) { + Transition t = this.getProcessTransitions().get(i); + t.setIndex(i); + lpnProc.addTransition(t); + + } + // Inputs + for (int i=0; i< this.getProcessInput().size(); i++) { + Variable var = this.getProcessInput().get(i); + lpnProc.addInput(var.getName(), var.getType(), var.getInitValue()); + } + // Outputs + for (int i=0; i< this.getProcessOutput().size(); i++) { + Variable var = this.getProcessOutput().get(i); + lpnProc.addOutput(var.getName(), var.getType(), var.getInitValue()); + } + // Internal + for (int i=0; i< this.getProcessInternal().size(); i++) { + Variable var = this.getProcessInternal().get(i); + lpnProc.addInternal(var.getName(), var.getType(), var.getInitValue()); + } + return lpnProc; + } + + public void setStateMachineFlag(boolean isSM) { + isStateMachine = isSM; + } + + public boolean getStateMachineFlag() { + return isStateMachine; + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/Vertex.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/Vertex.java new file mode 100644 index 000000000..164ff398e --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/Vertex.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn.LpnDecomposition; + +import java.util.HashMap; + +import edu.utah.ece.async.lema.verification.platu.main.Options; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Vertex { + public final Integer componentID; + private HashMap adjacencies; + private Edge edgeToMostConnectedNeighbor; + private int numVariables; + private int bestNetGain; + + public Vertex(Integer componentID, int numVariables) { + this.componentID = componentID; + this.numVariables = numVariables; + adjacencies = new HashMap(); + bestNetGain = MinusINF; + } + + public HashMap getAdjacencies() { + return this.adjacencies; + } + + /** + * This method calculates the best net gain when coalesce this vertex with one of its neighbor vertices. + * The net gain is calculated as follows: net gain = (# internal variables created after coalescing) - (# remaining global variables + * of the target process after coalescing). The term "internal" and "global" are defined here with respect to the coalesced component. + * @param maxNumVarsInOneComp + * @return + */ + public int calculateBestNetGain(int maxNumVarsInOneComp) { + for (Integer i : adjacencies.keySet()){ + Edge e = adjacencies.get(i); + Vertex targetVertex = e.target; + int numInternal = e.getWeight(); // e is the shared edge between this vertex and the target vertex. + if ((this.getNumVars() + targetVertex.getNumVars() - numInternal) > maxNumVarsInOneComp) { + bestNetGain = MinusINF; + if (Options.getDebugMode()) { + System.out.println("^^^^^^^^^^^^^^^^^^^^^^^"); + System.out.println("Component " + this.componentID + " has " + this.getNumVars() + " variable(s)."); + System.out.println("Component " + targetVertex.componentID + " has " + targetVertex.getNumVars() + " variable(s)."); + System.out.println("(" + this.componentID + " <- " + + targetVertex.componentID + ")" + " bestNetGain = " + bestNetGain); + System.out.println("vvvvvvvvvvvvvvvvvvvvvvv"); + } + } + else { + int numRemainGlobal = targetVertex.getAllEdgesWeights() - numInternal; + if (bestNetGain < numInternal - numRemainGlobal) { + bestNetGain = numInternal - numRemainGlobal; + edgeToMostConnectedNeighbor = e; + } + if (Options.getDebugMode()) + System.out.println("(" + this.componentID + " <- " + + targetVertex.componentID + ")" + " bestNetGain = " + bestNetGain); + } + + } + return bestNetGain; + } + + private int getNumVars() { + return numVariables; + } + + public int getBestNetGain() { + return bestNetGain; + } + + private int getAllEdgesWeights() { + int allEdgesWeights = 0; + for (Edge e : adjacencies.values()) { + allEdgesWeights = allEdgesWeights + e.getWeight(); + } + return allEdgesWeights; + } + + public static int MinusINF = -2147483648; + + public Vertex getMostConnectedNeighbor() { + return edgeToMostConnectedNeighbor.target; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/VertexComparator.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/VertexComparator.java new file mode 100644 index 000000000..c9377d566 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/LpnDecomposition/VertexComparator.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn.LpnDecomposition; + +import java.util.Comparator; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class VertexComparator implements Comparator{ + private int maxNumVarsInOneComp; + + public VertexComparator(Integer maxNumVarsInOneComp) { + this.maxNumVarsInOneComp = maxNumVarsInOneComp; + } + + @Override + public int compare(Vertex v1, Vertex v2) { + if (v1.calculateBestNetGain(maxNumVarsInOneComp) >= v2.calculateBestNetGain(maxNumVarsInOneComp)) + return -1; + return 1; +// else +// return 0; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ParseException.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ParseException.java new file mode 100644 index 000000000..4e42eb6ee --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ParseException.java @@ -0,0 +1,205 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */ +/* JavaCCOptions:KEEP_LINE_COL=null */ +package edu.utah.ece.async.lema.verification.lpn; + +/** + * This exception is thrown when parse errors are encountered. + * You can explicitly create objects of this exception type by + * calling the method generateParseException in the generated + * parser. + * + * You can modify this class to customize your error reporting + * mechanisms so long as you retain the public fields. + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ParseException extends Exception { + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /** + * This constructor is used by the method "generateParseException" + * in the generated parser. Calling this constructor generates + * a new object of this type with the fields "currentToken", + * "expectedTokenSequences", and "tokenImage" set. + */ + public ParseException(Token currentTokenVal, + int[][] expectedTokenSequencesVal, + String[] tokenImageVal + ) + { + super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal)); + currentToken = currentTokenVal; + expectedTokenSequences = expectedTokenSequencesVal; + tokenImage = tokenImageVal; + } + + /** + * The following constructors are for use by you for whatever + * purpose you can think of. Constructing the exception in this + * manner makes the exception behave in the normal way - i.e., as + * documented in the class "Throwable". The fields "errorToken", + * "expectedTokenSequences", and "tokenImage" do not contain + * relevant information. The JavaCC generated code does not use + * these constructors. + */ + + public ParseException() { + super(); + } + + /** Constructor with message. */ + public ParseException(String message) { + super(message); + } + + + /** + * This is the last token that has been consumed successfully. If + * this object has been created due to a parse error, the token + * followng this token will (therefore) be the first error token. + */ + public Token currentToken; + + /** + * Each entry in this array is an array of integers. Each array + * of integers represents a sequence of tokens (by their ordinal + * values) that is expected at this point of the parse. + */ + public int[][] expectedTokenSequences; + + /** + * This is a reference to the "tokenImage" array of the generated + * parser within which the parse error occurred. This array is + * defined in the generated ...Constants interface. + */ + public String[] tokenImage; + + /** + * It uses "currentToken" and "expectedTokenSequences" to generate a parse + * error message and returns it. If this object has been created + * due to a parse error, and you do not catch it (it gets thrown + * from the parser) the correct error message + * gets displayed. + */ + private static String initialise(Token currentToken, + int[][] expectedTokenSequences, + String[] tokenImage) { + String eol = System.getProperty("line.separator", "\n"); + StringBuffer expected = new StringBuffer(); + int maxSize = 0; + for (int i = 0; i < expectedTokenSequences.length; i++) { + if (maxSize < expectedTokenSequences[i].length) { + maxSize = expectedTokenSequences[i].length; + } + for (int j = 0; j < expectedTokenSequences[i].length; j++) { + expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' '); + } + if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { + expected.append("..."); + } + expected.append(eol).append(" "); + } + String retval = "Encountered \""; + Token tok = currentToken.next; + for (int i = 0; i < maxSize; i++) { + if (i != 0) retval += " "; + if (tok.kind == 0) { + retval += tokenImage[0]; + break; + } + retval += " " + tokenImage[tok.kind]; + retval += " \""; + retval += add_escapes(tok.image); + retval += " \""; + tok = tok.next; + } + retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn; + retval += "." + eol; + if (expectedTokenSequences.length == 1) { + retval += "Was expecting:" + eol + " "; + } else { + retval += "Was expecting one of:" + eol + " "; + } + retval += expected.toString(); + return retval; + } + + /** + * The end of line string for this machine. + */ + protected String eol = System.getProperty("line.separator", "\n"); + + /** + * Used to convert raw characters to their escaped version + * when these raw version cannot be used as part of an ASCII + * string literal. + */ + static String add_escapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case 0 : + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); + } + +} +/* JavaCC - OriginalChecksum=3de8a380650a6d52449760a316ba5b6e (do not edit this line) */ diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Parser.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Parser.java new file mode 100644 index 000000000..705d02def --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Parser.java @@ -0,0 +1,1467 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* Generated By:JavaCC: Do not edit this line. Parser.java */ + package edu.utah.ece.async.lema.verification.lpn; +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ + public class Parser implements ParserConstants { + + public Parser (String property) { + this(new java.io.ByteArrayInputStream(property.getBytes())); + } + + public boolean parseProperty() { + try { + Goal(); + return true; + } + catch (Exception e) { + System.out.println(e.toString()); + return false; + } + } + + public static void main(String [] args) { + try { + Parser p = new Parser(System.in); + //Parser p = new Parser(args[0]); + p.Goal(); + } + catch (Exception e) { + System.out.println(e.toString()); + } + + } + + final public void Goal() throws ParseException { + label_1: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case MINF: + case MAXF: + case IDIV: + case FLOOR: + case CEIL: + case UNIFORM: + case NORMAL: + case EXPONENTIAL: + case GAMMA: + case LOGNORMAL: + case CHISQ: + case LAPLACE: + case CAUCHY: + case RAYLEIGH: + case POISSON: + case BINOMIAL: + case BERNOULLI: + case BITNOT: + case BITOR: + case BITAND: + case BITXOR: + case INT: + case BOOL: + case BIT: + case RATE: + case OBRACE: + case BOOL_FALSE: + case BOOL_TRUE: + case EG: + case EF: + case AG: + case AF: + case Pr: + case Ss: + case INF: + case ID: + case INTEGER: + case REAL: + case MINUS: + case OPAR: + case NOT: + break; + default: + jj_la1[0] = jj_gen; + break label_1; + } + Property(); + } + jj_consume_token(0); + } + + final public void Property() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case OBRACE: + case EG: + case EF: + case AG: + case AF: + Props(); + break; + case MINF: + case MAXF: + case IDIV: + case FLOOR: + case CEIL: + case UNIFORM: + case NORMAL: + case EXPONENTIAL: + case GAMMA: + case LOGNORMAL: + case CHISQ: + case LAPLACE: + case CAUCHY: + case RAYLEIGH: + case POISSON: + case BINOMIAL: + case BERNOULLI: + case BITNOT: + case BITOR: + case BITAND: + case BITXOR: + case INT: + case BOOL: + case BIT: + case RATE: + case BOOL_FALSE: + case BOOL_TRUE: + case Pr: + case Ss: + case INF: + case ID: + case INTEGER: + case REAL: + case MINUS: + case OPAR: + case NOT: + Probproperty(); + break; + default: + jj_la1[1] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void Probproperty() throws ParseException { + if (jj_2_1(3)) { + jj_consume_token(Pr); + Relop(); + jj_consume_token(REAL); + jj_consume_token(OBRACE); + Probprop(); + jj_consume_token(CBRACE); + } else if (jj_2_2(2)) { + jj_consume_token(Pr); + jj_consume_token(OBRACE); + Probprop(); + jj_consume_token(CBRACE); + } else if (jj_2_3(2)) { + jj_consume_token(Pr); + jj_consume_token(EQUAL); + jj_consume_token(QMARK); + jj_consume_token(OBRACE); + Probprop(); + jj_consume_token(CBRACE); + } else if (jj_2_4(3)) { + jj_consume_token(Ss); + Relop(); + jj_consume_token(REAL); + jj_consume_token(OBRACE); + Probproperty(); + jj_consume_token(CBRACE); + } else if (jj_2_5(2)) { + jj_consume_token(Ss); + jj_consume_token(OBRACE); + Probproperty(); + jj_consume_token(CBRACE); + } else if (jj_2_6(2)) { + jj_consume_token(Ss); + jj_consume_token(EQUAL); + jj_consume_token(QMARK); + jj_consume_token(OBRACE); + Probproperty(); + jj_consume_token(CBRACE); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case MINF: + case MAXF: + case IDIV: + case FLOOR: + case CEIL: + case UNIFORM: + case NORMAL: + case EXPONENTIAL: + case GAMMA: + case LOGNORMAL: + case CHISQ: + case LAPLACE: + case CAUCHY: + case RAYLEIGH: + case POISSON: + case BINOMIAL: + case BERNOULLI: + case BITNOT: + case BITOR: + case BITAND: + case BITXOR: + case INT: + case BOOL: + case BIT: + case RATE: + case BOOL_FALSE: + case BOOL_TRUE: + case INF: + case ID: + case INTEGER: + case REAL: + case MINUS: + case OPAR: + case NOT: + Hsf(); + break; + default: + jj_la1[2] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + + final public void Probprop() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case PG: + jj_consume_token(PG); + Bound(); + jj_consume_token(OPAR); + Probproperty(); + jj_consume_token(CPAR); + break; + case PF: + jj_consume_token(PF); + Bound(); + jj_consume_token(OPAR); + Probproperty(); + jj_consume_token(CPAR); + break; + case MINF: + case MAXF: + case IDIV: + case FLOOR: + case CEIL: + case UNIFORM: + case NORMAL: + case EXPONENTIAL: + case GAMMA: + case LOGNORMAL: + case CHISQ: + case LAPLACE: + case CAUCHY: + case RAYLEIGH: + case POISSON: + case BINOMIAL: + case BERNOULLI: + case BITNOT: + case BITOR: + case BITAND: + case BITXOR: + case INT: + case BOOL: + case BIT: + case RATE: + case BOOL_FALSE: + case BOOL_TRUE: + case Pr: + case Ss: + case INF: + case ID: + case INTEGER: + case REAL: + case MINUS: + case OPAR: + case NOT: + Probproperty(); + jj_consume_token(PU); + Bound(); + Probproperty(); + break; + default: + jj_la1[3] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + +//void Props(): +//{} +//{ +// LOOKAHEAD(3) Prop() Andprop() +// | LOOKAHEAD(3) Prop() Orprop() +// | LOOKAHEAD(3) Prop() Impliesprop() +// | Prop() +//} + final public void Props() throws ParseException { + Prop(); + Props_prime(); + } + + final public void Props_prime() throws ParseException { + Andprop(); + } + + final public void Andprop() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case AND: + jj_consume_token(AND); + Prop(); + Andprop(); + break; + default: + jj_la1[4] = jj_gen; + + } + } + + final public void Orprop() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case OR: + jj_consume_token(OR); + Prop(); + Orprop(); + break; + default: + jj_la1[5] = jj_gen; + + } + } + + final public void Impliesprop() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case MINUS: + jj_consume_token(MINUS); + jj_consume_token(GREATERTHAN); + Prop(); + Impliesprop(); + break; + default: + jj_la1[6] = jj_gen; + + } + } + +//void Prop(): +//{} +//{ +// LOOKAHEAD(3) Fronttype() Bound() Hsf() +// | Fronttype() Bound() Prop() +// | Midprop() +//} + final public void Prop() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case EG: + case EF: + case AG: + case AF: + Fronttype(); + Bound(); + jj_consume_token(OPAR); + Prop_prime(); + jj_consume_token(CPAR); + break; + case OBRACE: + Midprop(); + break; + default: + jj_la1[7] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void Prop_prime() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case MINF: + case MAXF: + case IDIV: + case FLOOR: + case CEIL: + case UNIFORM: + case NORMAL: + case EXPONENTIAL: + case GAMMA: + case LOGNORMAL: + case CHISQ: + case LAPLACE: + case CAUCHY: + case RAYLEIGH: + case POISSON: + case BINOMIAL: + case BERNOULLI: + case BITNOT: + case BITOR: + case BITAND: + case BITXOR: + case INT: + case BOOL: + case BIT: + case RATE: + case BOOL_FALSE: + case BOOL_TRUE: + case INF: + case ID: + case INTEGER: + case REAL: + case MINUS: + case OPAR: + case NOT: + Hsf(); + break; + case EG: + case EF: + case AG: + case AF: + Fronttype(); + Bound(); + jj_consume_token(OPAR); + Prop_prime(); + jj_consume_token(CPAR); + break; + case OBRACE: + Midprop(); + break; + default: + jj_la1[8] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + +// void Midprop(): +//{} +//{ +// Propinner() +//} + final public void Midprop() throws ParseException { + jj_consume_token(OBRACE); + Propinner(); + jj_consume_token(CBRACE); + } + +//void Propinner(): +//{} +//{ +// LOOKAHEAD(3) Prop() Midtype() Bound() Prop() +// | LOOKAHEAD(3) Prop() Midtype() Bound() Hsf() +// | LOOKAHEAD(3) Hsf() Midtype() Bound() Prop() +// | Hsf() Midtype() Bound() Hsf() +//} + final public void Propinner() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case MINF: + case MAXF: + case IDIV: + case FLOOR: + case CEIL: + case UNIFORM: + case NORMAL: + case EXPONENTIAL: + case GAMMA: + case LOGNORMAL: + case CHISQ: + case LAPLACE: + case CAUCHY: + case RAYLEIGH: + case POISSON: + case BINOMIAL: + case BERNOULLI: + case BITNOT: + case BITOR: + case BITAND: + case BITXOR: + case INT: + case BOOL: + case BIT: + case RATE: + case BOOL_FALSE: + case BOOL_TRUE: + case INF: + case ID: + case INTEGER: + case REAL: + case MINUS: + case OPAR: + case NOT: + Hsf(); + Midtype(); + Bound(); + Propinner_prime(); + break; + case OBRACE: + case EG: + case EF: + case AG: + case AF: + Prop(); + Midtype(); + Bound(); + Propinner_prime(); + break; + default: + jj_la1[9] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void Propinner_prime() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case OBRACE: + case EG: + case EF: + case AG: + case AF: + Prop(); + break; + case MINF: + case MAXF: + case IDIV: + case FLOOR: + case CEIL: + case UNIFORM: + case NORMAL: + case EXPONENTIAL: + case GAMMA: + case LOGNORMAL: + case CHISQ: + case LAPLACE: + case CAUCHY: + case RAYLEIGH: + case POISSON: + case BINOMIAL: + case BERNOULLI: + case BITNOT: + case BITOR: + case BITAND: + case BITXOR: + case INT: + case BOOL: + case BIT: + case RATE: + case BOOL_FALSE: + case BOOL_TRUE: + case INF: + case ID: + case INTEGER: + case REAL: + case MINUS: + case OPAR: + case NOT: + Hsf(); + break; + default: + jj_la1[10] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void Fronttype() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case AG: + jj_consume_token(AG); + break; + case AF: + jj_consume_token(AF); + break; + case EG: + jj_consume_token(EG); + break; + case EF: + jj_consume_token(EF); + break; + default: + jj_la1[11] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void Midtype() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case AU: + jj_consume_token(AU); + break; + case EU: + jj_consume_token(EU); + break; + default: + jj_la1[12] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void Bound() throws ParseException { + if (jj_2_7(2)) { + jj_consume_token(OSQUARE); + Relop(); + Hsf(); + jj_consume_token(CSQUARE); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case OSQUARE: + jj_consume_token(OSQUARE); + Hsf(); + jj_consume_token(COMMA); + Hsf(); + jj_consume_token(CSQUARE); + break; + default: + jj_la1[13] = jj_gen; + + } + } + } + + final public void Hsf() throws ParseException { + Andexpr(); + Hsf_prime(); + } + + final public void Hsf_prime() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case OR: + jj_consume_token(OR); + Andexpr(); + Hsf_prime(); + break; + case IMPLIC: + jj_consume_token(IMPLIC); + Andexpr(); + Hsf_prime(); + break; + default: + jj_la1[14] = jj_gen; + + } + } + + final public void Andexpr() throws ParseException { + Relation(); + Andexpr_prime(); + } + + final public void Andexpr_prime() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case AND: + jj_consume_token(AND); + Relation(); + Andexpr_prime(); + break; + default: + jj_la1[15] = jj_gen; + + } + } + + final public void Relation() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case MINF: + case MAXF: + case IDIV: + case FLOOR: + case CEIL: + case UNIFORM: + case NORMAL: + case EXPONENTIAL: + case GAMMA: + case LOGNORMAL: + case CHISQ: + case LAPLACE: + case CAUCHY: + case RAYLEIGH: + case POISSON: + case BINOMIAL: + case BERNOULLI: + case BITNOT: + case BITOR: + case BITAND: + case BITXOR: + case INT: + case BOOL: + case RATE: + case BOOL_FALSE: + case BOOL_TRUE: + case INF: + case ID: + case INTEGER: + case REAL: + case MINUS: + case OPAR: + Arithexpr(); + Relation_prime(); + break; + case NOT: + jj_consume_token(NOT); + Relation(); + break; + case BIT: + jj_consume_token(BIT); + jj_consume_token(OPAR); + Arithexpr(); + jj_consume_token(COMMA); + Arithexpr(); + jj_consume_token(CPAR); + break; + default: + jj_la1[16] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void Relation_prime() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case EQUAL: + case LESSTHAN: + case GREATERTHAN: + case GEQ: + case LEQ: + Relop(); + Arithexpr(); + break; + default: + jj_la1[17] = jj_gen; + + } + } + + final public void Arithexpr() throws ParseException { + Multexpr(); + Arithexpr_prime(); + } + + final public void Arithexpr_prime() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case PLUS: + jj_consume_token(PLUS); + Multexpr(); + Arithexpr_prime(); + break; + case MINUS: + jj_consume_token(MINUS); + Multexpr(); + Arithexpr_prime(); + break; + default: + jj_la1[18] = jj_gen; + + } + } + + final public void Multexpr() throws ParseException { + Term(); + Multexpr_prime(); + } + + final public void Multexpr_prime() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case MULT: + jj_consume_token(MULT); + Term(); + Multexpr_prime(); + break; + case DIV: + jj_consume_token(DIV); + Term(); + Multexpr_prime(); + break; + case MOD: + jj_consume_token(MOD); + Term(); + Multexpr_prime(); + break; + case POWER: + jj_consume_token(POWER); + Term(); + Multexpr_prime(); + break; + case ID: + Id(); + break; + default: + jj_la1[19] = jj_gen; + + } + } + + final public void Term() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case OPAR: + jj_consume_token(OPAR); + Hsf(); + jj_consume_token(CPAR); + break; + case ID: + Id(); + break; + case INTEGER: + jj_consume_token(INTEGER); + break; + case REAL: + jj_consume_token(REAL); + break; + case INF: + jj_consume_token(INF); + break; + case RATE: + jj_consume_token(RATE); + jj_consume_token(OPAR); + Id(); + jj_consume_token(CPAR); + break; + case INT: + jj_consume_token(INT); + jj_consume_token(OPAR); + Hsf(); + jj_consume_token(CPAR); + break; + case MINUS: + jj_consume_token(MINUS); + Term(); + break; + case BOOL_FALSE: + jj_consume_token(BOOL_FALSE); + break; + case BOOL_TRUE: + jj_consume_token(BOOL_TRUE); + break; + case FLOOR: + case CEIL: + case EXPONENTIAL: + case CHISQ: + case LAPLACE: + case CAUCHY: + case RAYLEIGH: + case POISSON: + case BERNOULLI: + case BITNOT: + case BOOL: + Unop(); + jj_consume_token(OPAR); + Arithexpr(); + jj_consume_token(CPAR); + break; + case MINF: + case MAXF: + case IDIV: + case UNIFORM: + case NORMAL: + case GAMMA: + case LOGNORMAL: + case BINOMIAL: + case BITOR: + case BITAND: + case BITXOR: + Binop(); + jj_consume_token(OPAR); + Arithexpr(); + jj_consume_token(COMMA); + Arithexpr(); + jj_consume_token(CPAR); + break; + default: + jj_la1[20] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void Relop() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case EQUAL: + jj_consume_token(EQUAL); + break; + default: + jj_la1[21] = jj_gen; + if (jj_2_8(2)) { + jj_consume_token(LESSTHAN); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case LEQ: + jj_consume_token(LEQ); + break; + default: + jj_la1[22] = jj_gen; + if (jj_2_9(2)) { + jj_consume_token(GREATERTHAN); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case GEQ: + jj_consume_token(GEQ); + break; + default: + jj_la1[23] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + } + } + } + + final public void Unop() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case BITNOT: + jj_consume_token(BITNOT); + break; + case EXPONENTIAL: + jj_consume_token(EXPONENTIAL); + break; + case CHISQ: + jj_consume_token(CHISQ); + break; + case LAPLACE: + jj_consume_token(LAPLACE); + break; + case CAUCHY: + jj_consume_token(CAUCHY); + break; + case RAYLEIGH: + jj_consume_token(RAYLEIGH); + break; + case POISSON: + jj_consume_token(POISSON); + break; + case BERNOULLI: + jj_consume_token(BERNOULLI); + break; + case BOOL: + jj_consume_token(BOOL); + break; + case FLOOR: + jj_consume_token(FLOOR); + break; + case CEIL: + jj_consume_token(CEIL); + break; + default: + jj_la1[24] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void Binop() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case BITOR: + jj_consume_token(BITOR); + break; + case BITAND: + jj_consume_token(BITAND); + break; + case BITXOR: + jj_consume_token(BITXOR); + break; + case UNIFORM: + jj_consume_token(UNIFORM); + break; + case NORMAL: + jj_consume_token(NORMAL); + break; + case GAMMA: + jj_consume_token(GAMMA); + break; + case LOGNORMAL: + jj_consume_token(LOGNORMAL); + break; + case BINOMIAL: + jj_consume_token(BINOMIAL); + break; + case MINF: + jj_consume_token(MINF); + break; + case MAXF: + jj_consume_token(MAXF); + break; + case IDIV: + jj_consume_token(IDIV); + break; + default: + jj_la1[25] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void Id() throws ParseException { + jj_consume_token(ID); + } + + private boolean jj_2_1(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_1(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(0, xla); } + } + + private boolean jj_2_2(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_2(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(1, xla); } + } + + private boolean jj_2_3(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_3(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(2, xla); } + } + + private boolean jj_2_4(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_4(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(3, xla); } + } + + private boolean jj_2_5(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_5(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(4, xla); } + } + + private boolean jj_2_6(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_6(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(5, xla); } + } + + private boolean jj_2_7(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_7(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(6, xla); } + } + + private boolean jj_2_8(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_8(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(7, xla); } + } + + private boolean jj_2_9(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_9(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(8, xla); } + } + + private boolean jj_3_9() { + if (jj_scan_token(GREATERTHAN)) return true; + return false; + } + + private boolean jj_3_6() { + if (jj_scan_token(Ss)) return true; + if (jj_scan_token(EQUAL)) return true; + return false; + } + + private boolean jj_3_8() { + if (jj_scan_token(LESSTHAN)) return true; + return false; + } + + private boolean jj_3_5() { + if (jj_scan_token(Ss)) return true; + if (jj_scan_token(OBRACE)) return true; + return false; + } + + private boolean jj_3_4() { + if (jj_scan_token(Ss)) return true; + if (jj_3R_2()) return true; + if (jj_scan_token(REAL)) return true; + return false; + } + + private boolean jj_3_3() { + if (jj_scan_token(Pr)) return true; + if (jj_scan_token(EQUAL)) return true; + return false; + } + + private boolean jj_3R_2() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(64)) { + jj_scanpos = xsp; + if (jj_3_8()) { + jj_scanpos = xsp; + if (jj_scan_token(106)) { + jj_scanpos = xsp; + if (jj_3_9()) { + jj_scanpos = xsp; + if (jj_scan_token(105)) return true; + } + } + } + } + return false; + } + + private boolean jj_3_2() { + if (jj_scan_token(Pr)) return true; + if (jj_scan_token(OBRACE)) return true; + return false; + } + + private boolean jj_3_1() { + if (jj_scan_token(Pr)) return true; + if (jj_3R_2()) return true; + if (jj_scan_token(REAL)) return true; + return false; + } + + private boolean jj_3_7() { + if (jj_scan_token(OSQUARE)) return true; + if (jj_3R_2()) return true; + return false; + } + + /** Generated Token Manager. */ + public ParserTokenManager token_source; + JavaCharStream jj_input_stream; + /** Current token. */ + public Token token; + /** Next token. */ + public Token jj_nt; + private int jj_ntk; + private Token jj_scanpos, jj_lastpos; + private int jj_la; + private int jj_gen; + final private int[] jj_la1 = new int[26]; + static private int[] jj_la1_0; + static private int[] jj_la1_1; + static private int[] jj_la1_2; + static private int[] jj_la1_3; + static { + jj_la1_init_0(); + jj_la1_init_1(); + jj_la1_init_2(); + jj_la1_init_3(); + } + private static void jj_la1_init_0() { + jj_la1_0 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,}; + } + private static void jj_la1_init_1() { + jj_la1_1 = new int[] {0x3fffffe,0x3fffffe,0x3fffffe,0x3fffffe,0x0,0x0,0x0,0x0,0x3fffffe,0x3fffffe,0x3fffffe,0x0,0x0,0x0,0x20000000,0x0,0x3fffffe,0x0,0x0,0x0,0x2fffffe,0x0,0x0,0x0,0x86f930,0x3906ce,}; + } + private static void jj_la1_init_2() { + jj_la1_2 = new int[] {0x8d41879a,0x8d41879a,0x8d400018,0x8d419818,0x0,0x0,0x80000000,0x782,0x8d40079a,0x8d40079a,0x8d40079a,0x780,0x60,0x20000,0x0,0x0,0x8d400018,0x80005,0xc0000000,0x1000000,0x8d400018,0x1,0x0,0x0,0x0,0x0,}; + } + private static void jj_la1_init_3() { + jj_la1_3 = new int[] {0x21,0x21,0x21,0x21,0x80,0x100,0x0,0x0,0x21,0x21,0x21,0x0,0x0,0x0,0x100,0x80,0x21,0x600,0x0,0x5c,0x1,0x0,0x400,0x200,0x0,0x0,}; + } + final private JJCalls[] jj_2_rtns = new JJCalls[9]; + private boolean jj_rescan = false; + private int jj_gc = 0; + + /** Constructor with InputStream. */ + public Parser(java.io.InputStream stream) { + this(stream, null); + } + /** Constructor with InputStream and supplied encoding */ + public Parser(java.io.InputStream stream, String encoding) { + try { jj_input_stream = new JavaCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source = new ParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 26; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream stream) { + ReInit(stream, null); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream stream, String encoding) { + try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 26; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Constructor. */ + public Parser(java.io.Reader stream) { + jj_input_stream = new JavaCharStream(stream, 1, 1); + token_source = new ParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 26; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader stream) { + jj_input_stream.ReInit(stream, 1, 1); + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 26; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Constructor with generated Token Manager. */ + public Parser(ParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 26; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(ParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 26; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + private Token jj_consume_token(int kind) throws ParseException { + Token oldToken; + if ((oldToken = token).next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + if (token.kind == kind) { + jj_gen++; + if (++jj_gc > 100) { + jj_gc = 0; + for (int i = 0; i < jj_2_rtns.length; i++) { + JJCalls c = jj_2_rtns[i]; + while (c != null) { + if (c.gen < jj_gen) c.first = null; + c = c.next; + } + } + } + return token; + } + token = oldToken; + jj_kind = kind; + throw generateParseException(); + } + + static private final class LookaheadSuccess extends java.lang.Error { + + /** + * + */ + private static final long serialVersionUID = 1L; } + final private LookaheadSuccess jj_ls = new LookaheadSuccess(); + private boolean jj_scan_token(int kind) { + if (jj_scanpos == jj_lastpos) { + jj_la--; + if (jj_scanpos.next == null) { + jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken(); + } else { + jj_lastpos = jj_scanpos = jj_scanpos.next; + } + } else { + jj_scanpos = jj_scanpos.next; + } + if (jj_rescan) { + int i = 0; Token tok = token; + while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; } + if (tok != null) jj_add_error_token(kind, i); + } + if (jj_scanpos.kind != kind) return true; + if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls; + return false; + } + + +/** Get the next Token. */ + final public Token getNextToken() { + if (token.next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + jj_gen++; + return token; + } + +/** Get the specific Token. */ + final public Token getToken(int index) { + Token t = token; + for (int i = 0; i < index; i++) { + if (t.next != null) t = t.next; + else t = t.next = token_source.getNextToken(); + } + return t; + } + + private int jj_ntk() { + if ((jj_nt=token.next) == null) + return (jj_ntk = (token.next=token_source.getNextToken()).kind); + return (jj_ntk = jj_nt.kind); + } + + private java.util.List jj_expentries = new java.util.ArrayList(); + private int[] jj_expentry; + private int jj_kind = -1; + private int[] jj_lasttokens = new int[100]; + private int jj_endpos; + + private void jj_add_error_token(int kind, int pos) { + if (pos >= 100) return; + if (pos == jj_endpos + 1) { + jj_lasttokens[jj_endpos++] = kind; + } else if (jj_endpos != 0) { + jj_expentry = new int[jj_endpos]; + for (int i = 0; i < jj_endpos; i++) { + jj_expentry[i] = jj_lasttokens[i]; + } + jj_entries_loop: for (java.util.Iterator it = jj_expentries.iterator(); it.hasNext();) { + int[] oldentry = (int[])(it.next()); + if (oldentry.length == jj_expentry.length) { + for (int i = 0; i < jj_expentry.length; i++) { + if (oldentry[i] != jj_expentry[i]) { + continue jj_entries_loop; + } + } + jj_expentries.add(jj_expentry); + break jj_entries_loop; + } + } + if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind; + } + } + + /** Generate ParseException. */ + public ParseException generateParseException() { + jj_expentries.clear(); + boolean[] la1tokens = new boolean[116]; + if (jj_kind >= 0) { + la1tokens[jj_kind] = true; + jj_kind = -1; + } + for (int i = 0; i < 26; i++) { + if (jj_la1[i] == jj_gen) { + for (int j = 0; j < 32; j++) { + if ((jj_la1_0[i] & (1< jj_gen) { + jj_la = p.arg; jj_lastpos = jj_scanpos = p.first; + switch (i) { + case 0: jj_3_1(); break; + case 1: jj_3_2(); break; + case 2: jj_3_3(); break; + case 3: jj_3_4(); break; + case 4: jj_3_5(); break; + case 5: jj_3_6(); break; + case 6: jj_3_7(); break; + case 7: jj_3_8(); break; + case 8: jj_3_9(); break; + } + } + p = p.next; + } while (p != null); + } catch(LookaheadSuccess ls) { } + } + jj_rescan = false; + } + + private void jj_save(int index, int xla) { + JJCalls p = jj_2_rtns[index]; + while (p.gen > jj_gen) { + if (p.next == null) { p = p.next = new JJCalls(); break; } + p = p.next; + } + p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla; + } + + static final class JJCalls { + int gen; + Token first; + int arg; + JJCalls next; + } + + } diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Parser.jj b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Parser.jj new file mode 100644 index 000000000..1388ebb3e --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Parser.jj @@ -0,0 +1,449 @@ +options { + JAVA_UNICODE_ESCAPE = true; + STATIC = false; +} + +PARSER_BEGIN(Parser) + + package lpn.parser; + + public class Parser { + + public Parser (String property) { + this(new java.io.ByteArrayInputStream(property.getBytes())); + } + + public boolean parseProperty() { + try { + Goal(); + return true; + } + catch (Exception e) { + System.out.println(e.toString()); + return false; + } + } + + public static void main(String [] args) { + try { + Parser p = new Parser(System.in); + //Parser p = new Parser(args[0]); + p.Goal(); + } + catch (Exception e) { + System.out.println(e.toString()); + } + + } + } + +PARSER_END(Parser) + + +TOKEN : { + | + | + "end"|"END")> | + "inputs"|"INPUTS")> | + "init_state"> | + "dummy"|"DUMMY")> | + "failtrans"|"FAILTRANS")> | + "variables"|"VARIABLES")> | + "integers"|"INTEGERS")> | + "noninp"|"NONINP")> | + "keep"|"KEEP")> | + "abstract"|"ABSTRACT")> | + "continuous"|"CONTINUOUS")> | + "rates"|"RATES")> | + "init_rates"|"INIT_RATES")> | + "init_vals"|"INIT_VALS")> | + "init_ints"|"INIT_INTS")> | + "invariants"|"INVARIANTS")> | + "enablings"|"ENABLINGS")> | + "assignments"|"ASSIGNMENTS")> | + "transition_rates"|"TRANSITION_RATES")> | + "rate_assignments"|"RATE_ASSIGNMENTS")> | + "int_assignments"|"INT_ASSIGNMENTS")> | + "delay_assignments"|"DELAY_ASSIGNMENTS")> | + "priority_assignments"|"PRIORITY_ASSIGNMENTS")> | + "boolean_assignments"|"BOOLEAN_ASSIGNMENTS")> | + "outputs"|"OUTPUTS")> | + "internal"|"INTERNAL")> | + "graph"|"GRAPH")> | + "property"|"PROPERTY")> | + "marking"|"MARKING)")>| + "name"|"NAME")> | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + "> | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + "> | + | + | + | + | + |)(|||)*> | + )+(()+)?("E")("+"|"-")?()+> | + )+> | + |"e"|"e-"|"E"|"E-"|"e"|"e-"|"E"|"E-"|"e+"|"E+"> | + <#LETTER: ["a"-"z"]|["A"-"Z"]|["_"]> | + <#DIGIT: ["0"-"9"]> | + | + | + | + | + | + | + | + | + | + | + | + ="> | + | + +} + +SKIP : { " " | "\t" | "\n" | "\r" | "\r\n" | )*"#"(~["@","\n"])*> | <#DELIM: ([" ", "\t"])+>} + +void Goal() : +{} +{ + (Property())* +} + +void Property(): +{} +{ + Props() + | Probproperty() +} + +void Probproperty(): +{} +{ + LOOKAHEAD(3) Relop() Probprop() + | LOOKAHEAD(2) Probprop() + | LOOKAHEAD(2) Probprop() + | LOOKAHEAD(3) Relop() Probproperty() + | LOOKAHEAD(2) Probproperty() + | LOOKAHEAD(2) Probproperty() + | Hsf() +} + +void Probprop(): +{} +{ + Bound() Probproperty() + | Bound() Probproperty() + | Probproperty() Bound() Probproperty() +} + +//void Props(): +//{} +//{ +// LOOKAHEAD(3) Prop() Andprop() +// | LOOKAHEAD(3) Prop() Orprop() +// | LOOKAHEAD(3) Prop() Impliesprop() +// | Prop() +//} + +void Props(): +{} +{ + Prop() Props_prime() +} + +void Props_prime(): +{} +{ + Andprop() + | Orprop() + | Impliesprop() +} + +void Andprop(): +{} +{ + Prop() Andprop() + | {} +} + +void Orprop(): +{} +{ + Prop() Orprop() + | {} +} + +void Impliesprop(): +{} +{ + Prop() Impliesprop() + | {} +} + +//void Prop(): +//{} +//{ +// LOOKAHEAD(3) Fronttype() Bound() Hsf() +// | Fronttype() Bound() Prop() +// | Midprop() +//} + +void Prop(): +{} +{ + Fronttype() Bound() Prop_prime() + | Midprop() +} + +void Prop_prime(): +{} +{ + Hsf() + | Fronttype() Bound() Prop_prime() + | Midprop() +} + +// void Midprop(): +//{} +//{ +// Propinner() +//} + + +void Midprop(): +{} +{ + Propinner() +} + +//void Propinner(): +//{} +//{ +// LOOKAHEAD(3) Prop() Midtype() Bound() Prop() +// | LOOKAHEAD(3) Prop() Midtype() Bound() Hsf() +// | LOOKAHEAD(3) Hsf() Midtype() Bound() Prop() +// | Hsf() Midtype() Bound() Hsf() +//} + +void Propinner(): +{} +{ + Hsf() Midtype() Bound() Propinner_prime() + | Prop() Midtype() Bound() Propinner_prime() +} + +void Propinner_prime(): +{} +{ + Prop() + | Hsf() +} + +void Fronttype(): +{} +{ + | | | +} + +void Midtype(): +{} +{ + | +} + +void Bound(): +{} +{ + LOOKAHEAD(2) Relop() Hsf() + | Hsf() Hsf() + | {} +} + +void Hsf(): +{} +{ + Andexpr() Hsf_prime() +} + +void Hsf_prime(): +{} +{ + Andexpr() Hsf_prime() + | Andexpr() Hsf_prime() + | {} +} + +void Andexpr(): +{} +{ + Relation() Andexpr_prime() +} + +void Andexpr_prime(): +{} +{ + Relation() Andexpr_prime() + | {} +} + +void Relation(): +{} +{ + Arithexpr() Relation_prime() + | Relation() + | Arithexpr() Arithexpr() +} + +void Relation_prime(): +{} +{ + Relop() Arithexpr() + | {} +} + +void Arithexpr(): +{} +{ + Multexpr() Arithexpr_prime() +} + +void Arithexpr_prime(): +{} +{ + Multexpr() Arithexpr_prime() + | Multexpr() Arithexpr_prime() + | {} +} + +void Multexpr(): +{} +{ + Term() Multexpr_prime() +} + +void Multexpr_prime(): +{} +{ + Term() Multexpr_prime() + |
Term() Multexpr_prime() + | Term() Multexpr_prime() + | Term() Multexpr_prime() + | Id() + | {} +} + +void Term(): +{} +{ + Hsf() + | Id() + | + | + | + | Id() + | Hsf() + | Term() + | + | + | Unop() Arithexpr() + | Binop() Arithexpr() Arithexpr() +} + +void Relop(): +{} +{ + + | LOOKAHEAD(2) + | + | LOOKAHEAD(2) + | +} + +void Unop(): +{} +{ + + | + | + | + | + | + | + | + | + | + | +} + +void Binop(): +{} +{ + + | + | + | + | + | + | + | + | + | + | +} + +void Id(): +{} +{ + +} + diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ParserConstants.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ParserConstants.java new file mode 100644 index 000000000..118f1a582 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ParserConstants.java @@ -0,0 +1,375 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* Generated By:JavaCC: Do not edit this line. ParserConstants.java */ +package edu.utah.ece.async.lema.verification.lpn; + + +/** + * Token literal values and constants. + * Generated by org.javacc.parser.OtherFilesGen#start() + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public interface ParserConstants { + + /** End of File. */ + int EOF = 0; + /** RegularExpression Id. */ + int DOT = 1; + /** RegularExpression Id. */ + int ATACS = 2; + /** RegularExpression Id. */ + int END = 3; + /** RegularExpression Id. */ + int INPUTS = 4; + /** RegularExpression Id. */ + int INIT_STATE = 5; + /** RegularExpression Id. */ + int DUMMYS = 6; + /** RegularExpression Id. */ + int FAILTRANS = 7; + /** RegularExpression Id. */ + int VARIABLES = 8; + /** RegularExpression Id. */ + int INTEGERS = 9; + /** RegularExpression Id. */ + int NONINPS = 10; + /** RegularExpression Id. */ + int KEEPS = 11; + /** RegularExpression Id. */ + int ABSTRACTS = 12; + /** RegularExpression Id. */ + int CONTINUOUS = 13; + /** RegularExpression Id. */ + int RATES = 14; + /** RegularExpression Id. */ + int INITRATES = 15; + /** RegularExpression Id. */ + int INITVALS = 16; + /** RegularExpression Id. */ + int INITINTS = 17; + /** RegularExpression Id. */ + int INVARIANTS = 18; + /** RegularExpression Id. */ + int ENABLINGS = 19; + /** RegularExpression Id. */ + int ASSIGNS = 20; + /** RegularExpression Id. */ + int TRANS_RATES = 21; + /** RegularExpression Id. */ + int RATE_ASSIGNS = 22; + /** RegularExpression Id. */ + int INT_ASSIGNS = 23; + /** RegularExpression Id. */ + int DELAY_ASSIGNS = 24; + /** RegularExpression Id. */ + int PRIORITY_ASSIGNS = 25; + /** RegularExpression Id. */ + int BOOL_ASSIGNS = 26; + /** RegularExpression Id. */ + int OUTPUTS = 27; + /** RegularExpression Id. */ + int INTERNAL = 28; + /** RegularExpression Id. */ + int GRAPH = 29; + /** RegularExpression Id. */ + int PROPERTY = 30; + /** RegularExpression Id. */ + int MARKING = 31; + /** RegularExpression Id. */ + int NAME = 32; + /** RegularExpression Id. */ + int MINF = 33; + /** RegularExpression Id. */ + int MAXF = 34; + /** RegularExpression Id. */ + int IDIV = 35; + /** RegularExpression Id. */ + int FLOOR = 36; + /** RegularExpression Id. */ + int CEIL = 37; + /** RegularExpression Id. */ + int UNIFORM = 38; + /** RegularExpression Id. */ + int NORMAL = 39; + /** RegularExpression Id. */ + int EXPONENTIAL = 40; + /** RegularExpression Id. */ + int GAMMA = 41; + /** RegularExpression Id. */ + int LOGNORMAL = 42; + /** RegularExpression Id. */ + int CHISQ = 43; + /** RegularExpression Id. */ + int LAPLACE = 44; + /** RegularExpression Id. */ + int CAUCHY = 45; + /** RegularExpression Id. */ + int RAYLEIGH = 46; + /** RegularExpression Id. */ + int POISSON = 47; + /** RegularExpression Id. */ + int BINOMIAL = 48; + /** RegularExpression Id. */ + int BERNOULLI = 49; + /** RegularExpression Id. */ + int BITNOT = 50; + /** RegularExpression Id. */ + int BITOR = 51; + /** RegularExpression Id. */ + int BITAND = 52; + /** RegularExpression Id. */ + int BITXOR = 53; + /** RegularExpression Id. */ + int INT = 54; + /** RegularExpression Id. */ + int BOOL = 55; + /** RegularExpression Id. */ + int BIT = 56; + /** RegularExpression Id. */ + int RATE = 57; + /** RegularExpression Id. */ + int VERIFY = 58; + /** RegularExpression Id. */ + int SEARCH = 59; + /** RegularExpression Id. */ + int ASSIGN = 60; + /** RegularExpression Id. */ + int IMPLIC = 61; + /** RegularExpression Id. */ + int COMMA = 62; + /** RegularExpression Id. */ + int QMARK = 63; + /** RegularExpression Id. */ + int EQUAL = 64; + /** RegularExpression Id. */ + int OBRACE = 65; + /** RegularExpression Id. */ + int LESSTHAN = 66; + /** RegularExpression Id. */ + int BOOL_FALSE = 67; + /** RegularExpression Id. */ + int BOOL_TRUE = 68; + /** RegularExpression Id. */ + int AU = 69; + /** RegularExpression Id. */ + int EU = 70; + /** RegularExpression Id. */ + int EG = 71; + /** RegularExpression Id. */ + int EF = 72; + /** RegularExpression Id. */ + int AG = 73; + /** RegularExpression Id. */ + int AF = 74; + /** RegularExpression Id. */ + int PG = 75; + /** RegularExpression Id. */ + int PF = 76; + /** RegularExpression Id. */ + int PU = 77; + /** RegularExpression Id. */ + int PX = 78; + /** RegularExpression Id. */ + int Pr = 79; + /** RegularExpression Id. */ + int Ss = 80; + /** RegularExpression Id. */ + int OSQUARE = 81; + /** RegularExpression Id. */ + int CSQUARE = 82; + /** RegularExpression Id. */ + int GREATERTHAN = 83; + /** RegularExpression Id. */ + int CBRACE = 84; + /** RegularExpression Id. */ + int DISABLE = 85; + /** RegularExpression Id. */ + int INF = 86; + /** RegularExpression Id. */ + int SYMBOL = 87; + /** RegularExpression Id. */ + int ID = 88; + /** RegularExpression Id. */ + int NUM = 89; + /** RegularExpression Id. */ + int INTEGER = 90; + /** RegularExpression Id. */ + int REAL = 91; + /** RegularExpression Id. */ + int LETTER = 92; + /** RegularExpression Id. */ + int DIGIT = 93; + /** RegularExpression Id. */ + int PLUS = 94; + /** RegularExpression Id. */ + int MINUS = 95; + /** RegularExpression Id. */ + int OPAR = 96; + /** RegularExpression Id. */ + int CPAR = 97; + /** RegularExpression Id. */ + int MULT = 98; + /** RegularExpression Id. */ + int MOD = 99; + /** RegularExpression Id. */ + int POWER = 100; + /** RegularExpression Id. */ + int NOT = 101; + /** RegularExpression Id. */ + int DIV = 102; + /** RegularExpression Id. */ + int AND = 103; + /** RegularExpression Id. */ + int OR = 104; + /** RegularExpression Id. */ + int GEQ = 105; + /** RegularExpression Id. */ + int LEQ = 106; + /** RegularExpression Id. */ + int SEMICOLON = 107; + /** RegularExpression Id. */ + int UNKNOWN = 108; + /** RegularExpression Id. */ + int COMMENTS = 114; + /** RegularExpression Id. */ + int DELIM = 115; + + /** Lexical state. */ + int DEFAULT = 0; + + /** Literal token values. */ + String[] tokenImage = { + "", + "\".\"", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "\"min\"", + "\"max\"", + "\"idiv\"", + "\"floor\"", + "\"ceil\"", + "\"uniform\"", + "\"normal\"", + "\"exponential\"", + "\"gamma\"", + "\"lognormal\"", + "\"chisq\"", + "\"laplace\"", + "\"cauchy\"", + "\"rayleigh\"", + "\"poisson\"", + "\"binomial\"", + "\"bernoulli\"", + "\"NOT\"", + "\"OR\"", + "\"AND\"", + "\"XOR\"", + "\"INT\"", + "\"BOOL\"", + "\"BIT\"", + "\"rate\"", + "\"verify\"", + "\"search\"", + "\":=\"", + "\"=>\"", + "\",\"", + "\"?\"", + "\"=\"", + "\"{\"", + "\"<\"", + "\"false\"", + "\"true\"", + "\"AU\"", + "\"EU\"", + "\"EG\"", + "\"EF\"", + "\"AG\"", + "\"AF\"", + "\"PG\"", + "\"PF\"", + "\"PU\"", + "\"PX\"", + "\"Pr\"", + "\"St\"", + "\"[\"", + "\"]\"", + "\">\"", + "\"}\"", + "\")d\"", + "\"inf\"", + "", + "", + "", + "", + "", + "", + "", + "\"+\"", + "\"-\"", + "\"(\"", + "\")\"", + "\"*\"", + "\"%\"", + "\"^\"", + "\"~\"", + "\"/\"", + "\"&\"", + "\"|\"", + "\">=\"", + "\"<=\"", + "\";\"", + "\"\\\\\"", + "\" \"", + "\"\\t\"", + "\"\\n\"", + "\"\\r\"", + "\"\\r\\n\"", + "", + "", + }; + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ParserTokenManager.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ParserTokenManager.java new file mode 100644 index 000000000..ec3a88712 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/ParserTokenManager.java @@ -0,0 +1,3726 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* Generated By:JavaCC: Do not edit this line. ParserTokenManager.java */ +package edu.utah.ece.async.lema.verification.lpn; + +/** + * Token Manager + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ParserTokenManager implements ParserConstants +{ + + /** Debug output. */ + public java.io.PrintStream debugStream = System.out; + /** Set debug output. */ + public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; } +private final int jjStopStringLiteralDfa_0(int pos, long active0, long active1) +{ + switch (pos) + { + case 0: + if ((active0 & 0x8000000000000000L) != 0L) + return 4; + if ((active0 & 0xffffffe00000000L) != 0L || (active1 & 0x41fff8L) != 0L) + { + jjmatchedKind = 88; + return 4; + } + if ((active1 & 0x600000000000L) != 0L) + return 627; + if ((active0 & 0x2L) != 0L) + return 13; + return -1; + case 1: + if ((active0 & 0x8000000000000L) != 0L || (active1 & 0x1ffe0L) != 0L) + return 4; + if ((active0 & 0xff7fffe00000000L) != 0L || (active1 & 0x400018L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 1; + return 4; + } + return -1; + case 2: + if ((active0 & 0x174000600000000L) != 0L || (active1 & 0x400000L) != 0L) + return 4; + if ((active0 & 0xe83fff800000000L) != 0L || (active1 & 0x18L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 2; + return 4; + } + return -1; + case 3: + if ((active0 & 0x280002800000000L) != 0L || (active1 & 0x10L) != 0L) + return 4; + if ((active0 & 0xc03ffd000000000L) != 0L || (active1 & 0x8L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 3; + return 4; + } + return -1; + case 4: + if ((active0 & 0xa1000000000L) != 0L || (active1 & 0x8L) != 0L) + return 4; + if ((active0 & 0xc03f5c000000000L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 4; + return 4; + } + return -1; + case 5: + if ((active0 & 0xc00208000000000L) != 0L) + return 4; + if ((active0 & 0x3d54000000000L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 5; + return 4; + } + return -1; + case 6: + if ((active0 & 0x904000000000L) != 0L) + return 4; + if ((active0 & 0x3450000000000L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 6; + return 4; + } + return -1; + case 7: + if ((active0 & 0x2050000000000L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 7; + return 4; + } + if ((active0 & 0x1400000000000L) != 0L) + return 4; + return -1; + case 8: + if ((active0 & 0x10000000000L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 8; + return 4; + } + if ((active0 & 0x2040000000000L) != 0L) + return 4; + return -1; + case 9: + if ((active0 & 0x10000000000L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 9; + return 4; + } + return -1; + default : + return -1; + } +} +private final int jjStartNfa_0(int pos, long active0, long active1) +{ + return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0, active1), pos + 1); +} +private int jjStopAtPos(int pos, int kind) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + return pos + 1; +} +private int jjMoveStringLiteralDfa0_0() +{ + switch(curChar) + { + case 9: + return jjStartNfaWithStates_0(0, 110, 627); + case 13: + jjmatchedKind = 112; + return jjMoveStringLiteralDfa1_0(0x0L, 0x2000000000000L); + case 32: + return jjStartNfaWithStates_0(0, 109, 627); + case 37: + return jjStopAtPos(0, 99); + case 38: + return jjStopAtPos(0, 103); + case 40: + return jjStopAtPos(0, 96); + case 41: + jjmatchedKind = 97; + return jjMoveStringLiteralDfa1_0(0x0L, 0x200000L); + case 42: + return jjStopAtPos(0, 98); + case 43: + return jjStopAtPos(0, 94); + case 44: + return jjStopAtPos(0, 62); + case 45: + return jjStopAtPos(0, 95); + case 46: + return jjStartNfaWithStates_0(0, 1, 13); + case 47: + return jjStopAtPos(0, 102); + case 58: + return jjMoveStringLiteralDfa1_0(0x1000000000000000L, 0x0L); + case 59: + return jjStopAtPos(0, 107); + case 60: + jjmatchedKind = 66; + return jjMoveStringLiteralDfa1_0(0x0L, 0x40000000000L); + case 61: + jjmatchedKind = 64; + return jjMoveStringLiteralDfa1_0(0x2000000000000000L, 0x0L); + case 62: + jjmatchedKind = 83; + return jjMoveStringLiteralDfa1_0(0x0L, 0x20000000000L); + case 63: + return jjStartNfaWithStates_0(0, 63, 4); + case 65: + return jjMoveStringLiteralDfa1_0(0x10000000000000L, 0x620L); + case 66: + return jjMoveStringLiteralDfa1_0(0x180000000000000L, 0x0L); + case 69: + return jjMoveStringLiteralDfa1_0(0x0L, 0x1c0L); + case 73: + return jjMoveStringLiteralDfa1_0(0x40000000000000L, 0x0L); + case 78: + return jjMoveStringLiteralDfa1_0(0x4000000000000L, 0x0L); + case 79: + return jjMoveStringLiteralDfa1_0(0x8000000000000L, 0x0L); + case 80: + return jjMoveStringLiteralDfa1_0(0x0L, 0xf800L); + case 83: + return jjMoveStringLiteralDfa1_0(0x0L, 0x10000L); + case 88: + return jjMoveStringLiteralDfa1_0(0x20000000000000L, 0x0L); + case 91: + return jjStopAtPos(0, 81); + case 92: + return jjStopAtPos(0, 108); + case 93: + return jjStopAtPos(0, 82); + case 94: + return jjStopAtPos(0, 100); + case 98: + return jjMoveStringLiteralDfa1_0(0x3000000000000L, 0x0L); + case 99: + return jjMoveStringLiteralDfa1_0(0x282000000000L, 0x0L); + case 101: + return jjMoveStringLiteralDfa1_0(0x10000000000L, 0x0L); + case 102: + return jjMoveStringLiteralDfa1_0(0x1000000000L, 0x8L); + case 103: + return jjMoveStringLiteralDfa1_0(0x20000000000L, 0x0L); + case 105: + return jjMoveStringLiteralDfa1_0(0x800000000L, 0x400000L); + case 108: + return jjMoveStringLiteralDfa1_0(0x140000000000L, 0x0L); + case 109: + return jjMoveStringLiteralDfa1_0(0x600000000L, 0x0L); + case 110: + return jjMoveStringLiteralDfa1_0(0x8000000000L, 0x0L); + case 112: + return jjMoveStringLiteralDfa1_0(0x800000000000L, 0x0L); + case 114: + return jjMoveStringLiteralDfa1_0(0x200400000000000L, 0x0L); + case 115: + return jjMoveStringLiteralDfa1_0(0x800000000000000L, 0x0L); + case 116: + return jjMoveStringLiteralDfa1_0(0x0L, 0x10L); + case 117: + return jjMoveStringLiteralDfa1_0(0x4000000000L, 0x0L); + case 118: + return jjMoveStringLiteralDfa1_0(0x400000000000000L, 0x0L); + case 123: + return jjStopAtPos(0, 65); + case 124: + return jjStopAtPos(0, 104); + case 125: + return jjStopAtPos(0, 84); + case 126: + return jjStopAtPos(0, 101); + default : + return jjMoveNfa_0(2, 0); + } +} +private int jjMoveStringLiteralDfa1_0(long active0, long active1) +{ + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(0, active0, active1); + return 1; + } + switch(curChar) + { + case 10: + if ((active1 & 0x2000000000000L) != 0L) + return jjStopAtPos(1, 113); + break; + case 61: + if ((active0 & 0x1000000000000000L) != 0L) + return jjStopAtPos(1, 60); + else if ((active1 & 0x20000000000L) != 0L) + return jjStopAtPos(1, 105); + else if ((active1 & 0x40000000000L) != 0L) + return jjStopAtPos(1, 106); + break; + case 62: + if ((active0 & 0x2000000000000000L) != 0L) + return jjStopAtPos(1, 61); + break; + case 70: + if ((active1 & 0x100L) != 0L) + return jjStartNfaWithStates_0(1, 72, 4); + else if ((active1 & 0x400L) != 0L) + return jjStartNfaWithStates_0(1, 74, 4); + else if ((active1 & 0x1000L) != 0L) + return jjStartNfaWithStates_0(1, 76, 4); + break; + case 71: + if ((active1 & 0x80L) != 0L) + return jjStartNfaWithStates_0(1, 71, 4); + else if ((active1 & 0x200L) != 0L) + return jjStartNfaWithStates_0(1, 73, 4); + else if ((active1 & 0x800L) != 0L) + return jjStartNfaWithStates_0(1, 75, 4); + break; + case 73: + return jjMoveStringLiteralDfa2_0(active0, 0x100000000000000L, active1, 0L); + case 78: + return jjMoveStringLiteralDfa2_0(active0, 0x50000000000000L, active1, 0L); + case 79: + return jjMoveStringLiteralDfa2_0(active0, 0xa4000000000000L, active1, 0L); + case 82: + if ((active0 & 0x8000000000000L) != 0L) + return jjStartNfaWithStates_0(1, 51, 4); + break; + case 85: + if ((active1 & 0x20L) != 0L) + return jjStartNfaWithStates_0(1, 69, 4); + else if ((active1 & 0x40L) != 0L) + return jjStartNfaWithStates_0(1, 70, 4); + else if ((active1 & 0x2000L) != 0L) + return jjStartNfaWithStates_0(1, 77, 4); + break; + case 88: + if ((active1 & 0x4000L) != 0L) + return jjStartNfaWithStates_0(1, 78, 4); + break; + case 97: + return jjMoveStringLiteralDfa2_0(active0, 0x200720400000000L, active1, 0x8L); + case 100: + if ((active1 & 0x200000L) != 0L) + return jjStopAtPos(1, 85); + return jjMoveStringLiteralDfa2_0(active0, 0x800000000L, active1, 0L); + case 101: + return jjMoveStringLiteralDfa2_0(active0, 0xc02002000000000L, active1, 0L); + case 104: + return jjMoveStringLiteralDfa2_0(active0, 0x80000000000L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa2_0(active0, 0x1000200000000L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa2_0(active0, 0x1000000000L, active1, 0L); + case 110: + return jjMoveStringLiteralDfa2_0(active0, 0x4000000000L, active1, 0x400000L); + case 111: + return jjMoveStringLiteralDfa2_0(active0, 0x848000000000L, active1, 0L); + case 114: + if ((active1 & 0x8000L) != 0L) + return jjStartNfaWithStates_0(1, 79, 4); + return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x10L); + case 116: + if ((active1 & 0x10000L) != 0L) + return jjStartNfaWithStates_0(1, 80, 4); + break; + case 120: + return jjMoveStringLiteralDfa2_0(active0, 0x10000000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(0, active0, active1); +} +private int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(0, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(1, active0, active1); + return 2; + } + switch(curChar) + { + case 68: + if ((active0 & 0x10000000000000L) != 0L) + return jjStartNfaWithStates_0(2, 52, 4); + break; + case 79: + return jjMoveStringLiteralDfa3_0(active0, 0x80000000000000L, active1, 0L); + case 82: + if ((active0 & 0x20000000000000L) != 0L) + return jjStartNfaWithStates_0(2, 53, 4); + break; + case 84: + if ((active0 & 0x4000000000000L) != 0L) + return jjStartNfaWithStates_0(2, 50, 4); + else if ((active0 & 0x40000000000000L) != 0L) + return jjStartNfaWithStates_0(2, 54, 4); + else if ((active0 & 0x100000000000000L) != 0L) + return jjStartNfaWithStates_0(2, 56, 4); + break; + case 97: + return jjMoveStringLiteralDfa3_0(active0, 0x800000000000000L, active1, 0L); + case 102: + if ((active1 & 0x400000L) != 0L) + return jjStartNfaWithStates_0(2, 86, 4); + break; + case 103: + return jjMoveStringLiteralDfa3_0(active0, 0x40000000000L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa3_0(active0, 0x886800000000L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x8L); + case 109: + return jjMoveStringLiteralDfa3_0(active0, 0x20000000000L, active1, 0L); + case 110: + if ((active0 & 0x200000000L) != 0L) + return jjStartNfaWithStates_0(2, 33, 4); + return jjMoveStringLiteralDfa3_0(active0, 0x1000000000000L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa3_0(active0, 0x1000000000L, active1, 0L); + case 112: + return jjMoveStringLiteralDfa3_0(active0, 0x110000000000L, active1, 0L); + case 114: + return jjMoveStringLiteralDfa3_0(active0, 0x402008000000000L, active1, 0L); + case 116: + return jjMoveStringLiteralDfa3_0(active0, 0x200000000000000L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa3_0(active0, 0x200000000000L, active1, 0x10L); + case 120: + if ((active0 & 0x400000000L) != 0L) + return jjStartNfaWithStates_0(2, 34, 4); + break; + case 121: + return jjMoveStringLiteralDfa3_0(active0, 0x400000000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(1, active0, active1); +} +private int jjMoveStringLiteralDfa3_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(1, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(2, active0, active1); + return 3; + } + switch(curChar) + { + case 76: + if ((active0 & 0x80000000000000L) != 0L) + return jjStartNfaWithStates_0(3, 55, 4); + break; + case 99: + return jjMoveStringLiteralDfa4_0(active0, 0x200000000000L, active1, 0L); + case 101: + if ((active0 & 0x200000000000000L) != 0L) + return jjStartNfaWithStates_0(3, 57, 4); + else if ((active1 & 0x10L) != 0L) + return jjStartNfaWithStates_0(3, 68, 4); + break; + case 102: + return jjMoveStringLiteralDfa4_0(active0, 0x4000000000L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa4_0(active0, 0x400000000000000L, active1, 0L); + case 108: + if ((active0 & 0x2000000000L) != 0L) + return jjStartNfaWithStates_0(3, 37, 4); + return jjMoveStringLiteralDfa4_0(active0, 0x500000000000L, active1, 0L); + case 109: + return jjMoveStringLiteralDfa4_0(active0, 0x28000000000L, active1, 0L); + case 110: + return jjMoveStringLiteralDfa4_0(active0, 0x2040000000000L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa4_0(active0, 0x1011000000000L, active1, 0L); + case 114: + return jjMoveStringLiteralDfa4_0(active0, 0x800000000000000L, active1, 0L); + case 115: + return jjMoveStringLiteralDfa4_0(active0, 0x880000000000L, active1, 0x8L); + case 118: + if ((active0 & 0x800000000L) != 0L) + return jjStartNfaWithStates_0(3, 35, 4); + break; + default : + break; + } + return jjStartNfa_0(2, active0, active1); +} +private int jjMoveStringLiteralDfa4_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(2, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(3, active0, active1); + return 4; + } + switch(curChar) + { + case 97: + if ((active0 & 0x20000000000L) != 0L) + return jjStartNfaWithStates_0(4, 41, 4); + return jjMoveStringLiteralDfa5_0(active0, 0x108000000000L, active1, 0L); + case 99: + return jjMoveStringLiteralDfa5_0(active0, 0x800000000000000L, active1, 0L); + case 101: + if ((active1 & 0x8L) != 0L) + return jjStartNfaWithStates_0(4, 67, 4); + return jjMoveStringLiteralDfa5_0(active0, 0x400000000000L, active1, 0L); + case 102: + return jjMoveStringLiteralDfa5_0(active0, 0x400000000000000L, active1, 0L); + case 104: + return jjMoveStringLiteralDfa5_0(active0, 0x200000000000L, active1, 0L); + case 109: + return jjMoveStringLiteralDfa5_0(active0, 0x1000000000000L, active1, 0L); + case 110: + return jjMoveStringLiteralDfa5_0(active0, 0x10000000000L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa5_0(active0, 0x2044000000000L, active1, 0L); + case 113: + if ((active0 & 0x80000000000L) != 0L) + return jjStartNfaWithStates_0(4, 43, 4); + break; + case 114: + if ((active0 & 0x1000000000L) != 0L) + return jjStartNfaWithStates_0(4, 36, 4); + break; + case 115: + return jjMoveStringLiteralDfa5_0(active0, 0x800000000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(3, active0, active1); +} +private int jjMoveStringLiteralDfa5_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(3, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(4, active0, 0L); + return 5; + } + switch(curChar) + { + case 99: + return jjMoveStringLiteralDfa6_0(active0, 0x100000000000L); + case 101: + return jjMoveStringLiteralDfa6_0(active0, 0x10000000000L); + case 104: + if ((active0 & 0x800000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 59, 4); + break; + case 105: + return jjMoveStringLiteralDfa6_0(active0, 0x1400000000000L); + case 108: + if ((active0 & 0x8000000000L) != 0L) + return jjStartNfaWithStates_0(5, 39, 4); + break; + case 111: + return jjMoveStringLiteralDfa6_0(active0, 0x800000000000L); + case 114: + return jjMoveStringLiteralDfa6_0(active0, 0x44000000000L); + case 117: + return jjMoveStringLiteralDfa6_0(active0, 0x2000000000000L); + case 121: + if ((active0 & 0x200000000000L) != 0L) + return jjStartNfaWithStates_0(5, 45, 4); + else if ((active0 & 0x400000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 58, 4); + break; + default : + break; + } + return jjStartNfa_0(4, active0, 0L); +} +private int jjMoveStringLiteralDfa6_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(4, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(5, active0, 0L); + return 6; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa7_0(active0, 0x1000000000000L); + case 101: + if ((active0 & 0x100000000000L) != 0L) + return jjStartNfaWithStates_0(6, 44, 4); + break; + case 103: + return jjMoveStringLiteralDfa7_0(active0, 0x400000000000L); + case 108: + return jjMoveStringLiteralDfa7_0(active0, 0x2000000000000L); + case 109: + if ((active0 & 0x4000000000L) != 0L) + return jjStartNfaWithStates_0(6, 38, 4); + return jjMoveStringLiteralDfa7_0(active0, 0x40000000000L); + case 110: + if ((active0 & 0x800000000000L) != 0L) + return jjStartNfaWithStates_0(6, 47, 4); + return jjMoveStringLiteralDfa7_0(active0, 0x10000000000L); + default : + break; + } + return jjStartNfa_0(5, active0, 0L); +} +private int jjMoveStringLiteralDfa7_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(5, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(6, active0, 0L); + return 7; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa8_0(active0, 0x40000000000L); + case 104: + if ((active0 & 0x400000000000L) != 0L) + return jjStartNfaWithStates_0(7, 46, 4); + break; + case 108: + if ((active0 & 0x1000000000000L) != 0L) + return jjStartNfaWithStates_0(7, 48, 4); + return jjMoveStringLiteralDfa8_0(active0, 0x2000000000000L); + case 116: + return jjMoveStringLiteralDfa8_0(active0, 0x10000000000L); + default : + break; + } + return jjStartNfa_0(6, active0, 0L); +} +private int jjMoveStringLiteralDfa8_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(6, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(7, active0, 0L); + return 8; + } + switch(curChar) + { + case 105: + if ((active0 & 0x2000000000000L) != 0L) + return jjStartNfaWithStates_0(8, 49, 4); + return jjMoveStringLiteralDfa9_0(active0, 0x10000000000L); + case 108: + if ((active0 & 0x40000000000L) != 0L) + return jjStartNfaWithStates_0(8, 42, 4); + break; + default : + break; + } + return jjStartNfa_0(7, active0, 0L); +} +private int jjMoveStringLiteralDfa9_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(7, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(8, active0, 0L); + return 9; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa10_0(active0, 0x10000000000L); + default : + break; + } + return jjStartNfa_0(8, active0, 0L); +} +private int jjMoveStringLiteralDfa10_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(8, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(9, active0, 0L); + return 10; + } + switch(curChar) + { + case 108: + if ((active0 & 0x10000000000L) != 0L) + return jjStartNfaWithStates_0(10, 40, 4); + break; + default : + break; + } + return jjStartNfa_0(9, active0, 0L); +} +private int jjStartNfaWithStates_0(int pos, int kind, int state) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return pos + 1; } + return jjMoveNfa_0(state, pos + 1); +} +static final long[] jjbitVec0 = { + 0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL +}; +static final long[] jjbitVec2 = { + 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL +}; +private int jjMoveNfa_0(int startState, int curPos) +{ + int startsAt = 0; + jjnewStateCnt = 627; + int i = 1; + jjstateSet[0] = startState; + int kind = 0x7fffffff; + for (;;) + { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) + { + long l = 1L << curChar; + do + { + switch(jjstateSet[--i]) + { + case 627: + if ((0x100000200L & l) != 0L) + jjCheckNAddTwoStates(9, 5); + else if (curChar == 35) + { + if (kind > 114) + kind = 114; + jjCheckNAdd(6); + } + if ((0x100000200L & l) != 0L) + jjCheckNAddTwoStates(8, 1); + else if (curChar == 35) + jjstateSet[jjnewStateCnt++] = 0; + break; + case 2: + if ((0x3ff000000000000L & l) != 0L) + { + if (kind > 90) + kind = 90; + jjCheckNAddStates(0, 25); + } + else if ((0x100000200L & l) != 0L) + jjCheckNAddStates(26, 29); + else if (curChar == 46) + jjAddStates(30, 88); + else if (curChar == 35) + { + if (kind > 114) + kind = 114; + jjCheckNAdd(6); + } + else if ((0x8000000200000000L & l) != 0L) + { + if (kind > 88) + kind = 88; + jjCheckNAdd(4); + } + if ((0x8000000200000000L & l) != 0L) + { + if (kind > 87) + kind = 87; + } + else if (curChar == 35) + jjstateSet[jjnewStateCnt++] = 0; + break; + case 1: + if (curChar == 35) + jjstateSet[jjnewStateCnt++] = 0; + break; + case 3: + if ((0x8000000200000000L & l) == 0L) + break; + if (kind > 88) + kind = 88; + jjCheckNAdd(4); + break; + case 4: + if ((0x83ff400200000000L & l) == 0L) + break; + if (kind > 88) + kind = 88; + jjCheckNAdd(4); + break; + case 5: + if (curChar != 35) + break; + if (kind > 114) + kind = 114; + jjCheckNAdd(6); + break; + case 6: + if ((0xfffffffffffffbffL & l) == 0L) + break; + if (kind > 114) + kind = 114; + jjCheckNAdd(6); + break; + case 7: + if ((0x100000200L & l) != 0L) + jjCheckNAddStates(26, 29); + break; + case 8: + if ((0x100000200L & l) != 0L) + jjCheckNAddTwoStates(8, 1); + break; + case 9: + if ((0x100000200L & l) != 0L) + jjCheckNAddTwoStates(9, 5); + break; + case 10: + if (curChar == 46) + jjAddStates(30, 88); + break; + case 552: + if (curChar == 41 && kind > 31) + kind = 31; + break; + case 568: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 90) + kind = 90; + jjCheckNAddStates(0, 25); + break; + case 569: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddStates(89, 91); + break; + case 570: + if (curChar == 46) + jjCheckNAdd(571); + break; + case 571: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(571, 572); + break; + case 573: + if ((0x280000000000L & l) != 0L) + jjCheckNAdd(574); + break; + case 574: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 89) + kind = 89; + jjCheckNAdd(574); + break; + case 575: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 90) + kind = 90; + jjCheckNAdd(575); + break; + case 576: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(576, 577); + break; + case 577: + if (curChar == 46) + jjCheckNAdd(578); + break; + case 578: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjCheckNAdd(578); + break; + case 579: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(579, 580); + break; + case 581: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjstateSet[jjnewStateCnt++] = 581; + break; + case 582: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(582, 585); + break; + case 583: + if (curChar == 45) + jjCheckNAdd(584); + break; + case 584: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjCheckNAdd(584); + break; + case 586: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(586, 587); + break; + case 588: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjstateSet[jjnewStateCnt++] = 588; + break; + case 589: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(589, 592); + break; + case 590: + if (curChar == 45) + jjCheckNAdd(591); + break; + case 591: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjCheckNAdd(591); + break; + case 593: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(593, 594); + break; + case 594: + if (curChar == 46) + jjCheckNAdd(595); + break; + case 595: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(595, 596); + break; + case 597: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjstateSet[jjnewStateCnt++] = 597; + break; + case 598: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(598, 599); + break; + case 599: + if (curChar == 46) + jjCheckNAdd(600); + break; + case 600: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(600, 603); + break; + case 601: + if (curChar == 45) + jjCheckNAdd(602); + break; + case 602: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjCheckNAdd(602); + break; + case 604: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(604, 605); + break; + case 605: + if (curChar == 46) + jjCheckNAdd(606); + break; + case 606: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(606, 607); + break; + case 608: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjstateSet[jjnewStateCnt++] = 608; + break; + case 609: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(609, 610); + break; + case 610: + if (curChar == 46) + jjCheckNAdd(611); + break; + case 611: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(611, 614); + break; + case 612: + if (curChar == 45) + jjCheckNAdd(613); + break; + case 613: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjCheckNAdd(613); + break; + case 615: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(615, 616); + break; + case 616: + if (curChar == 46) + jjCheckNAdd(617); + break; + case 617: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(617, 620); + break; + case 618: + if (curChar == 43) + jjCheckNAdd(619); + break; + case 619: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjCheckNAdd(619); + break; + case 621: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(621, 622); + break; + case 622: + if (curChar == 46) + jjCheckNAdd(623); + break; + case 623: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(623, 626); + break; + case 624: + if (curChar == 43) + jjCheckNAdd(625); + break; + case 625: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjCheckNAdd(625); + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + long l = 1L << (curChar & 077); + do + { + switch(jjstateSet[--i]) + { + case 13: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 566; + else if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 562; + else if (curChar == 77) + jjstateSet[jjnewStateCnt++] = 558; + else if (curChar == 109) + jjstateSet[jjnewStateCnt++] = 550; + else if (curChar == 80) + jjstateSet[jjnewStateCnt++] = 543; + else if (curChar == 112) + jjstateSet[jjnewStateCnt++] = 535; + else if (curChar == 71) + jjstateSet[jjnewStateCnt++] = 527; + else if (curChar == 103) + jjstateSet[jjnewStateCnt++] = 522; + else if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 517; + else if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 509; + else if (curChar == 79) + jjstateSet[jjnewStateCnt++] = 501; + else if (curChar == 111) + jjstateSet[jjnewStateCnt++] = 494; + else if (curChar == 66) + jjstateSet[jjnewStateCnt++] = 487; + else if (curChar == 98) + jjstateSet[jjnewStateCnt++] = 468; + else if (curChar == 68) + jjstateSet[jjnewStateCnt++] = 409; + else if (curChar == 100) + jjstateSet[jjnewStateCnt++] = 392; + else if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 345; + else if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 329; + else if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 313; + else if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 297; + else if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 281; + else if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 270; + else if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 259; + else if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 250; + else if (curChar == 67) + jjstateSet[jjnewStateCnt++] = 155; + else if (curChar == 99) + jjstateSet[jjnewStateCnt++] = 145; + else if (curChar == 75) + jjstateSet[jjnewStateCnt++] = 119; + else if (curChar == 107) + jjstateSet[jjnewStateCnt++] = 115; + else if (curChar == 86) + jjstateSet[jjnewStateCnt++] = 83; + else if (curChar == 118) + jjstateSet[jjnewStateCnt++] = 74; + else if (curChar == 70) + jjstateSet[jjnewStateCnt++] = 65; + else if (curChar == 102) + jjstateSet[jjnewStateCnt++] = 56; + if (curChar == 80) + jjstateSet[jjnewStateCnt++] = 449; + else if (curChar == 112) + jjstateSet[jjnewStateCnt++] = 429; + else if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 375; + else if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 360; + else if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 165; + else if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 160; + else if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 135; + else if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 127; + else if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 111; + else if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 105; + else if (curChar == 68) + jjstateSet[jjnewStateCnt++] = 47; + else if (curChar == 100) + jjstateSet[jjnewStateCnt++] = 42; + else if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 15; + else if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 12; + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 241; + else if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 231; + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 221; + else if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 212; + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 203; + else if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 194; + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 185; + else if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 175; + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 99; + else if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 91; + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 37; + else if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 27; + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 21; + break; + case 2: + case 4: + if ((0x7fffffe87fffffeL & l) == 0L) + break; + if (kind > 88) + kind = 88; + jjCheckNAdd(4); + break; + case 0: + if (curChar == 64) + kind = 2; + break; + case 6: + if ((0xfffffffffffffffeL & l) == 0L) + break; + if (kind > 114) + kind = 114; + jjstateSet[jjnewStateCnt++] = 6; + break; + case 11: + if (curChar == 100 && kind > 3) + kind = 3; + break; + case 12: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 11; + break; + case 14: + if (curChar == 68 && kind > 3) + kind = 3; + break; + case 15: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 14; + break; + case 16: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 15; + break; + case 17: + if (curChar == 115 && kind > 4) + kind = 4; + break; + case 18: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 17; + break; + case 19: + if (curChar == 117) + jjstateSet[jjnewStateCnt++] = 18; + break; + case 20: + if (curChar == 112) + jjstateSet[jjnewStateCnt++] = 19; + break; + case 21: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 20; + break; + case 22: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 21; + break; + case 23: + if (curChar == 83 && kind > 4) + kind = 4; + break; + case 24: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 23; + break; + case 25: + if (curChar == 85) + jjstateSet[jjnewStateCnt++] = 24; + break; + case 26: + if (curChar == 80) + jjstateSet[jjnewStateCnt++] = 25; + break; + case 27: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 26; + break; + case 28: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 27; + break; + case 29: + if (curChar == 101 && kind > 5) + kind = 5; + break; + case 30: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 29; + break; + case 31: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 30; + break; + case 32: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 31; + break; + case 33: + if (curChar == 115) + jjstateSet[jjnewStateCnt++] = 32; + break; + case 34: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 33; + break; + case 35: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 34; + break; + case 36: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 35; + break; + case 37: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 36; + break; + case 38: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 37; + break; + case 39: + if (curChar == 121 && kind > 6) + kind = 6; + break; + case 40: + if (curChar == 109) + jjstateSet[jjnewStateCnt++] = 39; + break; + case 41: + if (curChar == 109) + jjstateSet[jjnewStateCnt++] = 40; + break; + case 42: + if (curChar == 117) + jjstateSet[jjnewStateCnt++] = 41; + break; + case 43: + if (curChar == 100) + jjstateSet[jjnewStateCnt++] = 42; + break; + case 44: + if (curChar == 89 && kind > 6) + kind = 6; + break; + case 45: + if (curChar == 77) + jjstateSet[jjnewStateCnt++] = 44; + break; + case 46: + if (curChar == 77) + jjstateSet[jjnewStateCnt++] = 45; + break; + case 47: + if (curChar == 85) + jjstateSet[jjnewStateCnt++] = 46; + break; + case 48: + if (curChar == 68) + jjstateSet[jjnewStateCnt++] = 47; + break; + case 49: + if (curChar == 115 && kind > 7) + kind = 7; + break; + case 50: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 49; + break; + case 51: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 50; + break; + case 52: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 51; + break; + case 53: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 52; + break; + case 54: + if (curChar == 108) + jjstateSet[jjnewStateCnt++] = 53; + break; + case 55: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 54; + break; + case 56: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 55; + break; + case 57: + if (curChar == 102) + jjstateSet[jjnewStateCnt++] = 56; + break; + case 58: + if (curChar == 83 && kind > 7) + kind = 7; + break; + case 59: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 58; + break; + case 60: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 59; + break; + case 61: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 60; + break; + case 62: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 61; + break; + case 63: + if (curChar == 76) + jjstateSet[jjnewStateCnt++] = 62; + break; + case 64: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 63; + break; + case 65: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 64; + break; + case 66: + if (curChar == 70) + jjstateSet[jjnewStateCnt++] = 65; + break; + case 67: + if (curChar == 115 && kind > 8) + kind = 8; + break; + case 68: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 67; + break; + case 69: + if (curChar == 108) + jjstateSet[jjnewStateCnt++] = 68; + break; + case 70: + if (curChar == 98) + jjstateSet[jjnewStateCnt++] = 69; + break; + case 71: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 70; + break; + case 72: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 71; + break; + case 73: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 72; + break; + case 74: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 73; + break; + case 75: + if (curChar == 118) + jjstateSet[jjnewStateCnt++] = 74; + break; + case 76: + if (curChar == 83 && kind > 8) + kind = 8; + break; + case 77: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 76; + break; + case 78: + if (curChar == 76) + jjstateSet[jjnewStateCnt++] = 77; + break; + case 79: + if (curChar == 66) + jjstateSet[jjnewStateCnt++] = 78; + break; + case 80: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 79; + break; + case 81: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 80; + break; + case 82: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 81; + break; + case 83: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 82; + break; + case 84: + if (curChar == 86) + jjstateSet[jjnewStateCnt++] = 83; + break; + case 85: + if (curChar == 115 && kind > 9) + kind = 9; + break; + case 86: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 85; + break; + case 87: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 86; + break; + case 88: + if (curChar == 103) + jjstateSet[jjnewStateCnt++] = 87; + break; + case 89: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 88; + break; + case 90: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 89; + break; + case 91: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 90; + break; + case 92: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 91; + break; + case 93: + if (curChar == 83 && kind > 9) + kind = 9; + break; + case 94: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 93; + break; + case 95: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 94; + break; + case 96: + if (curChar == 71) + jjstateSet[jjnewStateCnt++] = 95; + break; + case 97: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 96; + break; + case 98: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 97; + break; + case 99: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 98; + break; + case 100: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 99; + break; + case 101: + if (curChar == 112 && kind > 10) + kind = 10; + break; + case 102: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 101; + break; + case 103: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 102; + break; + case 104: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 103; + break; + case 105: + if (curChar == 111) + jjstateSet[jjnewStateCnt++] = 104; + break; + case 106: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 105; + break; + case 107: + if (curChar == 80 && kind > 10) + kind = 10; + break; + case 108: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 107; + break; + case 109: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 108; + break; + case 110: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 109; + break; + case 111: + if (curChar == 79) + jjstateSet[jjnewStateCnt++] = 110; + break; + case 112: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 111; + break; + case 113: + if (curChar == 112 && kind > 11) + kind = 11; + break; + case 114: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 113; + break; + case 115: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 114; + break; + case 116: + if (curChar == 107) + jjstateSet[jjnewStateCnt++] = 115; + break; + case 117: + if (curChar == 80 && kind > 11) + kind = 11; + break; + case 118: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 117; + break; + case 119: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 118; + break; + case 120: + if (curChar == 75) + jjstateSet[jjnewStateCnt++] = 119; + break; + case 121: + if (curChar == 116 && kind > 12) + kind = 12; + break; + case 122: + if (curChar == 99) + jjstateSet[jjnewStateCnt++] = 121; + break; + case 123: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 122; + break; + case 124: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 123; + break; + case 125: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 124; + break; + case 126: + if (curChar == 115) + jjstateSet[jjnewStateCnt++] = 125; + break; + case 127: + if (curChar == 98) + jjstateSet[jjnewStateCnt++] = 126; + break; + case 128: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 127; + break; + case 129: + if (curChar == 84 && kind > 12) + kind = 12; + break; + case 130: + if (curChar == 67) + jjstateSet[jjnewStateCnt++] = 129; + break; + case 131: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 130; + break; + case 132: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 131; + break; + case 133: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 132; + break; + case 134: + if (curChar == 83) + jjstateSet[jjnewStateCnt++] = 133; + break; + case 135: + if (curChar == 66) + jjstateSet[jjnewStateCnt++] = 134; + break; + case 136: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 135; + break; + case 137: + if (curChar == 115 && kind > 13) + kind = 13; + break; + case 138: + if (curChar == 117) + jjstateSet[jjnewStateCnt++] = 137; + break; + case 139: + if (curChar == 111) + jjstateSet[jjnewStateCnt++] = 138; + break; + case 140: + if (curChar == 117) + jjstateSet[jjnewStateCnt++] = 139; + break; + case 141: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 140; + break; + case 142: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 141; + break; + case 143: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 142; + break; + case 144: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 143; + break; + case 145: + if (curChar == 111) + jjstateSet[jjnewStateCnt++] = 144; + break; + case 146: + if (curChar == 99) + jjstateSet[jjnewStateCnt++] = 145; + break; + case 147: + if (curChar == 83 && kind > 13) + kind = 13; + break; + case 148: + if (curChar == 85) + jjstateSet[jjnewStateCnt++] = 147; + break; + case 149: + if (curChar == 79) + jjstateSet[jjnewStateCnt++] = 148; + break; + case 150: + if (curChar == 85) + jjstateSet[jjnewStateCnt++] = 149; + break; + case 151: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 150; + break; + case 152: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 151; + break; + case 153: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 152; + break; + case 154: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 153; + break; + case 155: + if (curChar == 79) + jjstateSet[jjnewStateCnt++] = 154; + break; + case 156: + if (curChar == 67) + jjstateSet[jjnewStateCnt++] = 155; + break; + case 157: + if (curChar == 115 && kind > 14) + kind = 14; + break; + case 158: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 157; + break; + case 159: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 158; + break; + case 160: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 159; + break; + case 161: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 160; + break; + case 162: + if (curChar == 83 && kind > 14) + kind = 14; + break; + case 163: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 162; + break; + case 164: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 163; + break; + case 165: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 164; + break; + case 166: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 165; + break; + case 167: + if (curChar == 115 && kind > 15) + kind = 15; + break; + case 168: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 167; + break; + case 169: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 168; + break; + case 170: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 169; + break; + case 171: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 170; + break; + case 172: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 171; + break; + case 173: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 172; + break; + case 174: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 173; + break; + case 175: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 174; + break; + case 176: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 175; + break; + case 177: + if (curChar == 83 && kind > 15) + kind = 15; + break; + case 178: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 177; + break; + case 179: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 178; + break; + case 180: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 179; + break; + case 181: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 180; + break; + case 182: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 181; + break; + case 183: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 182; + break; + case 184: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 183; + break; + case 185: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 184; + break; + case 186: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 185; + break; + case 187: + if (curChar == 115 && kind > 16) + kind = 16; + break; + case 188: + if (curChar == 108) + jjstateSet[jjnewStateCnt++] = 187; + break; + case 189: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 188; + break; + case 190: + if (curChar == 118) + jjstateSet[jjnewStateCnt++] = 189; + break; + case 191: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 190; + break; + case 192: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 191; + break; + case 193: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 192; + break; + case 194: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 193; + break; + case 195: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 194; + break; + case 196: + if (curChar == 83 && kind > 16) + kind = 16; + break; + case 197: + if (curChar == 76) + jjstateSet[jjnewStateCnt++] = 196; + break; + case 198: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 197; + break; + case 199: + if (curChar == 86) + jjstateSet[jjnewStateCnt++] = 198; + break; + case 200: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 199; + break; + case 201: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 200; + break; + case 202: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 201; + break; + case 203: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 202; + break; + case 204: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 203; + break; + case 205: + if (curChar == 115 && kind > 17) + kind = 17; + break; + case 206: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 205; + break; + case 207: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 206; + break; + case 208: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 207; + break; + case 209: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 208; + break; + case 210: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 209; + break; + case 211: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 210; + break; + case 212: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 211; + break; + case 213: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 212; + break; + case 214: + if (curChar == 83 && kind > 17) + kind = 17; + break; + case 215: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 214; + break; + case 216: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 215; + break; + case 217: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 216; + break; + case 218: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 217; + break; + case 219: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 218; + break; + case 220: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 219; + break; + case 221: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 220; + break; + case 222: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 221; + break; + case 223: + if (curChar == 115 && kind > 18) + kind = 18; + break; + case 224: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 223; + break; + case 225: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 224; + break; + case 226: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 225; + break; + case 227: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 226; + break; + case 228: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 227; + break; + case 229: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 228; + break; + case 230: + if (curChar == 118) + jjstateSet[jjnewStateCnt++] = 229; + break; + case 231: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 230; + break; + case 232: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 231; + break; + case 233: + if (curChar == 83 && kind > 18) + kind = 18; + break; + case 234: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 233; + break; + case 235: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 234; + break; + case 236: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 235; + break; + case 237: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 236; + break; + case 238: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 237; + break; + case 239: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 238; + break; + case 240: + if (curChar == 86) + jjstateSet[jjnewStateCnt++] = 239; + break; + case 241: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 240; + break; + case 242: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 241; + break; + case 243: + if (curChar == 115 && kind > 19) + kind = 19; + break; + case 244: + if (curChar == 103) + jjstateSet[jjnewStateCnt++] = 243; + break; + case 245: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 244; + break; + case 246: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 245; + break; + case 247: + if (curChar == 108) + jjstateSet[jjnewStateCnt++] = 246; + break; + case 248: + if (curChar == 98) + jjstateSet[jjnewStateCnt++] = 247; + break; + case 249: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 248; + break; + case 250: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 249; + break; + case 251: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 250; + break; + case 252: + if (curChar == 83 && kind > 19) + kind = 19; + break; + case 253: + if (curChar == 71) + jjstateSet[jjnewStateCnt++] = 252; + break; + case 254: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 253; + break; + case 255: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 254; + break; + case 256: + if (curChar == 76) + jjstateSet[jjnewStateCnt++] = 255; + break; + case 257: + if (curChar == 66) + jjstateSet[jjnewStateCnt++] = 256; + break; + case 258: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 257; + break; + case 259: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 258; + break; + case 260: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 259; + break; + case 261: + if (curChar == 115 && kind > 20) + kind = 20; + break; + case 262: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 261; + break; + case 263: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 262; + break; + case 264: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 263; + break; + case 265: + if (curChar == 109) + jjstateSet[jjnewStateCnt++] = 264; + break; + case 266: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 265; + break; + case 267: + if (curChar == 103) + jjstateSet[jjnewStateCnt++] = 266; + break; + case 268: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 267; + break; + case 269: + if (curChar == 115) + jjstateSet[jjnewStateCnt++] = 268; + break; + case 270: + if (curChar == 115) + jjstateSet[jjnewStateCnt++] = 269; + break; + case 271: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 270; + break; + case 272: + if (curChar == 83 && kind > 20) + kind = 20; + break; + case 273: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 272; + break; + case 274: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 273; + break; + case 275: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 274; + break; + case 276: + if (curChar == 77) + jjstateSet[jjnewStateCnt++] = 275; + break; + case 277: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 276; + break; + case 278: + if (curChar == 71) + jjstateSet[jjnewStateCnt++] = 277; + break; + case 279: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 278; + break; + case 280: + if (curChar == 83) + jjstateSet[jjnewStateCnt++] = 279; + break; + case 281: + if (curChar == 83) + jjstateSet[jjnewStateCnt++] = 280; + break; + case 282: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 281; + break; + case 283: + if (curChar == 115 && kind > 21) + kind = 21; + break; + case 284: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 283; + break; + case 285: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 284; + break; + case 286: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 285; + break; + case 287: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 286; + break; + case 288: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 287; + break; + case 289: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 288; + break; + case 290: + if (curChar == 111) + jjstateSet[jjnewStateCnt++] = 289; + break; + case 291: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 290; + break; + case 292: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 291; + break; + case 293: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 292; + break; + case 294: + if (curChar == 115) + jjstateSet[jjnewStateCnt++] = 293; + break; + case 295: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 294; + break; + case 296: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 295; + break; + case 297: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 296; + break; + case 298: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 297; + break; + case 299: + if (curChar == 83 && kind > 21) + kind = 21; + break; + case 300: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 299; + break; + case 301: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 300; + break; + case 302: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 301; + break; + case 303: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 302; + break; + case 304: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 303; + break; + case 305: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 304; + break; + case 306: + if (curChar == 79) + jjstateSet[jjnewStateCnt++] = 305; + break; + case 307: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 306; + break; + case 308: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 307; + break; + case 309: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 308; + break; + case 310: + if (curChar == 83) + jjstateSet[jjnewStateCnt++] = 309; + break; + case 311: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 310; + break; + case 312: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 311; + break; + case 313: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 312; + break; + case 314: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 313; + break; + case 315: + if (curChar == 115 && kind > 22) + kind = 22; + break; + case 316: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 315; + break; + case 317: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 316; + break; + case 318: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 317; + break; + case 319: + if (curChar == 109) + jjstateSet[jjnewStateCnt++] = 318; + break; + case 320: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 319; + break; + case 321: + if (curChar == 103) + jjstateSet[jjnewStateCnt++] = 320; + break; + case 322: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 321; + break; + case 323: + if (curChar == 115) + jjstateSet[jjnewStateCnt++] = 322; + break; + case 324: + if (curChar == 115) + jjstateSet[jjnewStateCnt++] = 323; + break; + case 325: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 324; + break; + case 326: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 325; + break; + case 327: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 326; + break; + case 328: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 327; + break; + case 329: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 328; + break; + case 330: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 329; + break; + case 331: + if (curChar == 83 && kind > 22) + kind = 22; + break; + case 332: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 331; + break; + case 333: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 332; + break; + case 334: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 333; + break; + case 335: + if (curChar == 77) + jjstateSet[jjnewStateCnt++] = 334; + break; + case 336: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 335; + break; + case 337: + if (curChar == 71) + jjstateSet[jjnewStateCnt++] = 336; + break; + case 338: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 337; + break; + case 339: + if (curChar == 83) + jjstateSet[jjnewStateCnt++] = 338; + break; + case 340: + if (curChar == 83) + jjstateSet[jjnewStateCnt++] = 339; + break; + case 341: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 340; + break; + case 342: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 341; + break; + case 343: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 342; + break; + case 344: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 343; + break; + case 345: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 344; + break; + case 346: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 345; + break; + case 347: + if (curChar == 115 && kind > 23) + kind = 23; + break; + case 348: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 347; + break; + case 349: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 348; + break; + case 350: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 349; + break; + case 351: + if (curChar == 109) + jjstateSet[jjnewStateCnt++] = 350; + break; + case 352: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 351; + break; + case 353: + if (curChar == 103) + jjstateSet[jjnewStateCnt++] = 352; + break; + case 354: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 353; + break; + case 355: + if (curChar == 115) + jjstateSet[jjnewStateCnt++] = 354; + break; + case 356: + if (curChar == 115) + jjstateSet[jjnewStateCnt++] = 355; + break; + case 357: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 356; + break; + case 358: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 357; + break; + case 359: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 358; + break; + case 360: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 359; + break; + case 361: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 360; + break; + case 362: + if (curChar == 83 && kind > 23) + kind = 23; + break; + case 363: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 362; + break; + case 364: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 363; + break; + case 365: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 364; + break; + case 366: + if (curChar == 77) + jjstateSet[jjnewStateCnt++] = 365; + break; + case 367: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 366; + break; + case 368: + if (curChar == 71) + jjstateSet[jjnewStateCnt++] = 367; + break; + case 369: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 368; + break; + case 370: + if (curChar == 83) + jjstateSet[jjnewStateCnt++] = 369; + break; + case 371: + if (curChar == 83) + jjstateSet[jjnewStateCnt++] = 370; + break; + case 372: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 371; + break; + case 373: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 372; + break; + case 374: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 373; + break; + case 375: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 374; + break; + case 376: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 375; + break; + case 377: + if (curChar == 115 && kind > 24) + kind = 24; + break; + case 378: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 377; + break; + case 379: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 378; + break; + case 380: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 379; + break; + case 381: + if (curChar == 109) + jjstateSet[jjnewStateCnt++] = 380; + break; + case 382: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 381; + break; + case 383: + if (curChar == 103) + jjstateSet[jjnewStateCnt++] = 382; + break; + case 384: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 383; + break; + case 385: + if (curChar == 115) + jjstateSet[jjnewStateCnt++] = 384; + break; + case 386: + if (curChar == 115) + jjstateSet[jjnewStateCnt++] = 385; + break; + case 387: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 386; + break; + case 388: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 387; + break; + case 389: + if (curChar == 121) + jjstateSet[jjnewStateCnt++] = 388; + break; + case 390: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 389; + break; + case 391: + if (curChar == 108) + jjstateSet[jjnewStateCnt++] = 390; + break; + case 392: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 391; + break; + case 393: + if (curChar == 100) + jjstateSet[jjnewStateCnt++] = 392; + break; + case 394: + if (curChar == 83 && kind > 24) + kind = 24; + break; + case 395: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 394; + break; + case 396: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 395; + break; + case 397: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 396; + break; + case 398: + if (curChar == 77) + jjstateSet[jjnewStateCnt++] = 397; + break; + case 399: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 398; + break; + case 400: + if (curChar == 71) + jjstateSet[jjnewStateCnt++] = 399; + break; + case 401: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 400; + break; + case 402: + if (curChar == 83) + jjstateSet[jjnewStateCnt++] = 401; + break; + case 403: + if (curChar == 83) + jjstateSet[jjnewStateCnt++] = 402; + break; + case 404: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 403; + break; + case 405: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 404; + break; + case 406: + if (curChar == 89) + jjstateSet[jjnewStateCnt++] = 405; + break; + case 407: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 406; + break; + case 408: + if (curChar == 76) + jjstateSet[jjnewStateCnt++] = 407; + break; + case 409: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 408; + break; + case 410: + if (curChar == 68) + jjstateSet[jjnewStateCnt++] = 409; + break; + case 411: + if (curChar == 115 && kind > 25) + kind = 25; + break; + case 412: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 411; + break; + case 413: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 412; + break; + case 414: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 413; + break; + case 415: + if (curChar == 109) + jjstateSet[jjnewStateCnt++] = 414; + break; + case 416: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 415; + break; + case 417: + if (curChar == 103) + jjstateSet[jjnewStateCnt++] = 416; + break; + case 418: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 417; + break; + case 419: + if (curChar == 115) + jjstateSet[jjnewStateCnt++] = 418; + break; + case 420: + if (curChar == 115) + jjstateSet[jjnewStateCnt++] = 419; + break; + case 421: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 420; + break; + case 422: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 421; + break; + case 423: + if (curChar == 121) + jjstateSet[jjnewStateCnt++] = 422; + break; + case 424: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 423; + break; + case 425: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 424; + break; + case 426: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 425; + break; + case 427: + if (curChar == 111) + jjstateSet[jjnewStateCnt++] = 426; + break; + case 428: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 427; + break; + case 429: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 428; + break; + case 430: + if (curChar == 112) + jjstateSet[jjnewStateCnt++] = 429; + break; + case 431: + if (curChar == 83 && kind > 25) + kind = 25; + break; + case 432: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 431; + break; + case 433: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 432; + break; + case 434: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 433; + break; + case 435: + if (curChar == 77) + jjstateSet[jjnewStateCnt++] = 434; + break; + case 436: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 435; + break; + case 437: + if (curChar == 71) + jjstateSet[jjnewStateCnt++] = 436; + break; + case 438: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 437; + break; + case 439: + if (curChar == 83) + jjstateSet[jjnewStateCnt++] = 438; + break; + case 440: + if (curChar == 83) + jjstateSet[jjnewStateCnt++] = 439; + break; + case 441: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 440; + break; + case 442: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 441; + break; + case 443: + if (curChar == 89) + jjstateSet[jjnewStateCnt++] = 442; + break; + case 444: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 443; + break; + case 445: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 444; + break; + case 446: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 445; + break; + case 447: + if (curChar == 79) + jjstateSet[jjnewStateCnt++] = 446; + break; + case 448: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 447; + break; + case 449: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 448; + break; + case 450: + if (curChar == 80) + jjstateSet[jjnewStateCnt++] = 449; + break; + case 451: + if (curChar == 115 && kind > 26) + kind = 26; + break; + case 452: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 451; + break; + case 453: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 452; + break; + case 454: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 453; + break; + case 455: + if (curChar == 109) + jjstateSet[jjnewStateCnt++] = 454; + break; + case 456: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 455; + break; + case 457: + if (curChar == 103) + jjstateSet[jjnewStateCnt++] = 456; + break; + case 458: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 457; + break; + case 459: + if (curChar == 115) + jjstateSet[jjnewStateCnt++] = 458; + break; + case 460: + if (curChar == 115) + jjstateSet[jjnewStateCnt++] = 459; + break; + case 461: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 460; + break; + case 462: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 461; + break; + case 463: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 462; + break; + case 464: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 463; + break; + case 465: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 464; + break; + case 466: + if (curChar == 108) + jjstateSet[jjnewStateCnt++] = 465; + break; + case 467: + if (curChar == 111) + jjstateSet[jjnewStateCnt++] = 466; + break; + case 468: + if (curChar == 111) + jjstateSet[jjnewStateCnt++] = 467; + break; + case 469: + if (curChar == 98) + jjstateSet[jjnewStateCnt++] = 468; + break; + case 470: + if (curChar == 83 && kind > 26) + kind = 26; + break; + case 471: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 470; + break; + case 472: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 471; + break; + case 473: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 472; + break; + case 474: + if (curChar == 77) + jjstateSet[jjnewStateCnt++] = 473; + break; + case 475: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 474; + break; + case 476: + if (curChar == 71) + jjstateSet[jjnewStateCnt++] = 475; + break; + case 477: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 476; + break; + case 478: + if (curChar == 83) + jjstateSet[jjnewStateCnt++] = 477; + break; + case 479: + if (curChar == 83) + jjstateSet[jjnewStateCnt++] = 478; + break; + case 480: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 479; + break; + case 481: + if (curChar == 95) + jjstateSet[jjnewStateCnt++] = 480; + break; + case 482: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 481; + break; + case 483: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 482; + break; + case 484: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 483; + break; + case 485: + if (curChar == 76) + jjstateSet[jjnewStateCnt++] = 484; + break; + case 486: + if (curChar == 79) + jjstateSet[jjnewStateCnt++] = 485; + break; + case 487: + if (curChar == 79) + jjstateSet[jjnewStateCnt++] = 486; + break; + case 488: + if (curChar == 66) + jjstateSet[jjnewStateCnt++] = 487; + break; + case 489: + if (curChar == 115 && kind > 27) + kind = 27; + break; + case 490: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 489; + break; + case 491: + if (curChar == 117) + jjstateSet[jjnewStateCnt++] = 490; + break; + case 492: + if (curChar == 112) + jjstateSet[jjnewStateCnt++] = 491; + break; + case 493: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 492; + break; + case 494: + if (curChar == 117) + jjstateSet[jjnewStateCnt++] = 493; + break; + case 495: + if (curChar == 111) + jjstateSet[jjnewStateCnt++] = 494; + break; + case 496: + if (curChar == 83 && kind > 27) + kind = 27; + break; + case 497: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 496; + break; + case 498: + if (curChar == 85) + jjstateSet[jjnewStateCnt++] = 497; + break; + case 499: + if (curChar == 80) + jjstateSet[jjnewStateCnt++] = 498; + break; + case 500: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 499; + break; + case 501: + if (curChar == 85) + jjstateSet[jjnewStateCnt++] = 500; + break; + case 502: + if (curChar == 79) + jjstateSet[jjnewStateCnt++] = 501; + break; + case 503: + if (curChar == 108 && kind > 28) + kind = 28; + break; + case 504: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 503; + break; + case 505: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 504; + break; + case 506: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 505; + break; + case 507: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 506; + break; + case 508: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 507; + break; + case 509: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 508; + break; + case 510: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 509; + break; + case 511: + if (curChar == 76 && kind > 28) + kind = 28; + break; + case 512: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 511; + break; + case 513: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 512; + break; + case 514: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 513; + break; + case 515: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 514; + break; + case 516: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 515; + break; + case 517: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 516; + break; + case 518: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 517; + break; + case 519: + if (curChar == 104 && kind > 29) + kind = 29; + break; + case 520: + if (curChar == 112) + jjstateSet[jjnewStateCnt++] = 519; + break; + case 521: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 520; + break; + case 522: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 521; + break; + case 523: + if (curChar == 103) + jjstateSet[jjnewStateCnt++] = 522; + break; + case 524: + if (curChar == 72 && kind > 29) + kind = 29; + break; + case 525: + if (curChar == 80) + jjstateSet[jjnewStateCnt++] = 524; + break; + case 526: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 525; + break; + case 527: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 526; + break; + case 528: + if (curChar == 71) + jjstateSet[jjnewStateCnt++] = 527; + break; + case 529: + if (curChar == 121 && kind > 30) + kind = 30; + break; + case 530: + if (curChar == 116) + jjstateSet[jjnewStateCnt++] = 529; + break; + case 531: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 530; + break; + case 532: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 531; + break; + case 533: + if (curChar == 112) + jjstateSet[jjnewStateCnt++] = 532; + break; + case 534: + if (curChar == 111) + jjstateSet[jjnewStateCnt++] = 533; + break; + case 535: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 534; + break; + case 536: + if (curChar == 112) + jjstateSet[jjnewStateCnt++] = 535; + break; + case 537: + if (curChar == 89 && kind > 30) + kind = 30; + break; + case 538: + if (curChar == 84) + jjstateSet[jjnewStateCnt++] = 537; + break; + case 539: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 538; + break; + case 540: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 539; + break; + case 541: + if (curChar == 80) + jjstateSet[jjnewStateCnt++] = 540; + break; + case 542: + if (curChar == 79) + jjstateSet[jjnewStateCnt++] = 541; + break; + case 543: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 542; + break; + case 544: + if (curChar == 80) + jjstateSet[jjnewStateCnt++] = 543; + break; + case 545: + if (curChar == 103 && kind > 31) + kind = 31; + break; + case 546: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 545; + break; + case 547: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 546; + break; + case 548: + if (curChar == 107) + jjstateSet[jjnewStateCnt++] = 547; + break; + case 549: + if (curChar == 114) + jjstateSet[jjnewStateCnt++] = 548; + break; + case 550: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 549; + break; + case 551: + if (curChar == 109) + jjstateSet[jjnewStateCnt++] = 550; + break; + case 553: + if (curChar == 71) + jjstateSet[jjnewStateCnt++] = 552; + break; + case 554: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 553; + break; + case 555: + if (curChar == 73) + jjstateSet[jjnewStateCnt++] = 554; + break; + case 556: + if (curChar == 75) + jjstateSet[jjnewStateCnt++] = 555; + break; + case 557: + if (curChar == 82) + jjstateSet[jjnewStateCnt++] = 556; + break; + case 558: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 557; + break; + case 559: + if (curChar == 77) + jjstateSet[jjnewStateCnt++] = 558; + break; + case 560: + if (curChar == 101 && kind > 32) + kind = 32; + break; + case 561: + if (curChar == 109) + jjstateSet[jjnewStateCnt++] = 560; + break; + case 562: + if (curChar == 97) + jjstateSet[jjnewStateCnt++] = 561; + break; + case 563: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 562; + break; + case 564: + if (curChar == 69 && kind > 32) + kind = 32; + break; + case 565: + if (curChar == 77) + jjstateSet[jjnewStateCnt++] = 564; + break; + case 566: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 565; + break; + case 567: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 566; + break; + case 572: + if (curChar == 69) + jjAddStates(92, 93); + break; + case 580: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 581; + break; + case 585: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 583; + break; + case 587: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 588; + break; + case 592: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 590; + break; + case 596: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 597; + break; + case 603: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 601; + break; + case 607: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 608; + break; + case 614: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 612; + break; + case 620: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 618; + break; + case 626: + if (curChar == 69) + jjstateSet[jjnewStateCnt++] = 624; + break; + default : break; + } + } while(i != startsAt); + } + else + { + int hiByte = (curChar >> 8); + int i1 = hiByte >> 6; + long l1 = 1L << (hiByte & 077); + int i2 = (curChar & 0xff) >> 6; + long l2 = 1L << (curChar & 077); + do + { + switch(jjstateSet[--i]) + { + case 6: + if (!jjCanMove_0(hiByte, i1, i2, l1, l2)) + break; + if (kind > 114) + kind = 114; + jjstateSet[jjnewStateCnt++] = 6; + break; + default : break; + } + } while(i != startsAt); + } + if (kind != 0x7fffffff) + { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 627 - (jjnewStateCnt = startsAt))) + return curPos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return curPos; } + } +} +static final int[] jjnextStates = { + 569, 570, 572, 575, 576, 577, 579, 580, 582, 585, 586, 587, 589, 592, 593, 594, + 598, 599, 604, 605, 609, 610, 615, 616, 621, 622, 8, 1, 9, 5, 13, 16, + 22, 28, 38, 43, 48, 57, 66, 75, 84, 92, 100, 106, 112, 116, 120, 128, + 136, 146, 156, 161, 166, 176, 186, 195, 204, 213, 222, 232, 242, 251, 260, 271, + 282, 298, 314, 330, 346, 361, 376, 393, 410, 430, 450, 469, 488, 495, 502, 510, + 518, 523, 528, 536, 544, 551, 559, 563, 567, 569, 570, 572, 573, 574, +}; +private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2) +{ + switch(hiByte) + { + case 0: + return ((jjbitVec2[i2] & l2) != 0L); + default : + if ((jjbitVec0[i1] & l1) != 0L) + return true; + return false; + } +} + +/** Token literal values. */ +public static final String[] jjstrLiteralImages = { +"", "\56", null, null, null, null, null, null, null, null, null, null, null, +null, null, null, null, null, null, null, null, null, null, null, null, null, null, +null, null, null, null, null, null, "\155\151\156", "\155\141\170", +"\151\144\151\166", "\146\154\157\157\162", "\143\145\151\154", "\165\156\151\146\157\162\155", +"\156\157\162\155\141\154", "\145\170\160\157\156\145\156\164\151\141\154", "\147\141\155\155\141", +"\154\157\147\156\157\162\155\141\154", "\143\150\151\163\161", "\154\141\160\154\141\143\145", +"\143\141\165\143\150\171", "\162\141\171\154\145\151\147\150", "\160\157\151\163\163\157\156", +"\142\151\156\157\155\151\141\154", "\142\145\162\156\157\165\154\154\151", "\116\117\124", "\117\122", +"\101\116\104", "\130\117\122", "\111\116\124", "\102\117\117\114", "\102\111\124", +"\162\141\164\145", "\166\145\162\151\146\171", "\163\145\141\162\143\150", "\72\75", "\75\76", +"\54", "\77", "\75", "\173", "\74", "\146\141\154\163\145", "\164\162\165\145", +"\101\125", "\105\125", "\105\107", "\105\106", "\101\107", "\101\106", "\120\107", +"\120\106", "\120\125", "\120\130", "\120\162", "\123\164", "\133", "\135", "\76", "\175", +"\51\144", "\151\156\146", null, null, null, null, null, null, null, "\53", "\55", "\50", +"\51", "\52", "\45", "\136", "\176", "\57", "\46", "\174", "\76\75", "\74\75", "\73", +"\134", null, null, null, null, null, null, null, }; + +/** Lexer state names. */ +public static final String[] lexStateNames = { + "DEFAULT", +}; +static final long[] jjtoToken = { + 0xffffffffffffffffL, 0x1fffcfffffffL, +}; +static final long[] jjtoSkip = { + 0x0L, 0x7e00000000000L, +}; +protected JavaCharStream input_stream; +private final int[] jjrounds = new int[627]; +private final int[] jjstateSet = new int[1254]; +protected char curChar; +/** Constructor. */ +public ParserTokenManager(JavaCharStream stream){ + if (JavaCharStream.staticFlag) + throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer."); + input_stream = stream; +} + +/** Constructor. */ +public ParserTokenManager(JavaCharStream stream, int lexState){ + this(stream); + SwitchTo(lexState); +} + +/** Reinitialise parser. */ +public void ReInit(JavaCharStream stream) +{ + jjmatchedPos = jjnewStateCnt = 0; + curLexState = defaultLexState; + input_stream = stream; + ReInitRounds(); +} +private void ReInitRounds() +{ + int i; + jjround = 0x80000001; + for (i = 627; i-- > 0;) + jjrounds[i] = 0x80000000; +} + +/** Reinitialise parser. */ +public void ReInit(JavaCharStream stream, int lexState) +{ + ReInit(stream); + SwitchTo(lexState); +} + +/** Switch to specified lex state. */ +public void SwitchTo(int lexState) +{ + if (lexState >= 1 || lexState < 0) + throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE); +curLexState = lexState; +} + +protected Token jjFillToken() +{ + final Token t; + final String curTokenImage; + final int beginLine; + final int endLine; + final int beginColumn; + final int endColumn; + String im = jjstrLiteralImages[jjmatchedKind]; + curTokenImage = (im == null) ? input_stream.GetImage() : im; + beginLine = input_stream.getBeginLine(); + beginColumn = input_stream.getBeginColumn(); + endLine = input_stream.getEndLine(); + endColumn = input_stream.getEndColumn(); + t = Token.newToken(jjmatchedKind, curTokenImage); + + t.beginLine = beginLine; + t.endLine = endLine; + t.beginColumn = beginColumn; + t.endColumn = endColumn; + + return t; +} + +int curLexState = 0; +int defaultLexState = 0; +int jjnewStateCnt; +int jjround; +int jjmatchedPos; +int jjmatchedKind; + +/** Get the next Token. */ +public Token getNextToken() +{ + Token matchedToken; + int curPos = 0; + + EOFLoop : + for (;;) + { + try + { + curChar = input_stream.BeginToken(); + } + catch(java.io.IOException e) + { + jjmatchedKind = 0; + matchedToken = jjFillToken(); + return matchedToken; + } + + try { input_stream.backup(0); + while (curChar <= 10 && (0x400L & (1L << curChar)) != 0L) + curChar = input_stream.BeginToken(); + } + catch (java.io.IOException e1) { continue EOFLoop; } + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_0(); + if (jjmatchedKind != 0x7fffffff) + { + if (jjmatchedPos + 1 < curPos) + input_stream.backup(curPos - jjmatchedPos - 1); + if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) + { + matchedToken = jjFillToken(); + return matchedToken; + } + continue EOFLoop; + } + int error_line = input_stream.getEndLine(); + int error_column = input_stream.getEndColumn(); + String error_after = null; + boolean EOFSeen = false; + try { input_stream.readChar(); input_stream.backup(1); } + catch (java.io.IOException e1) { + EOFSeen = true; + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + if (curChar == '\n' || curChar == '\r') { + error_line++; + error_column = 0; + } + else + error_column++; + } + if (!EOFSeen) { + input_stream.backup(1); + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + } + throw new TokenMgrError(EOFSeen, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR); + } +} + +private void jjCheckNAdd(int state) +{ + if (jjrounds[state] != jjround) + { + jjstateSet[jjnewStateCnt++] = state; + jjrounds[state] = jjround; + } +} +private void jjAddStates(int start, int end) +{ + do { + jjstateSet[jjnewStateCnt++] = jjnextStates[start]; + } while (start++ != end); +} +private void jjCheckNAddTwoStates(int state1, int state2) +{ + jjCheckNAdd(state1); + jjCheckNAdd(state2); +} + +private void jjCheckNAddStates(int start, int end) +{ + do { + jjCheckNAdd(jjnextStates[start]); + } while (start++ != end); +} + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Place.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Place.java new file mode 100644 index 000000000..6e2c7220b --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Place.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn; + +import java.util.ArrayList; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Place { + + private String name; + + private Boolean marked; + + private ArrayList preset; + + private ArrayList postset; + + public Place(String name) { + this.name = name; + marked = false; + preset = new ArrayList(); + postset = new ArrayList(); + } + + public Place(String name, boolean marking) { + this.name = name; + marked = marking; + preset = new ArrayList(); + postset = new ArrayList(); + } + + public void addPreset(Transition transition) { + preset.add(transition); + } + + public void addPostset(Transition transition) { + postset.add(transition); + } + + public void removePreset(Transition transition) { + preset.remove(transition); + } + + public void removePostset(Transition transition) { + postset.remove(transition); + } + + public void setMarking(boolean marking) { + marked = marking; + } + + public boolean isMarked() { + return marked; + } + + public boolean isConnected() { + return (preset.size() > 0 || postset.size() > 0); + } + + public boolean containsPreset(String name) { + return preset.contains(name); + } + + public boolean containsPostset(String name) { + return postset.contains(name); + } + + public void setName(String newName) { + this.name = newName; + } + + public String getName() { + return name; + } + + public Transition[] getPreset() { + Transition[] array = new Transition[preset.size()]; + int i = 0; + for (Transition t : preset) { + array[i++] = t; + } + return array; + } + + public Transition[] getPostset() { + Transition[] array = new Transition[postset.size()]; + int i = 0; + for (Transition t : postset) { + array[i++] = t; + } + return array; + } + + @Override + public String toString() { + return name; + } + + public void changeName(String newName){ + name = newName; + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Token.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Token.java new file mode 100644 index 000000000..1edf43a62 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Token.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */ +/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +package edu.utah.ece.async.lema.verification.lpn; + +/** + * Describes the input token stream. + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Token implements java.io.Serializable { + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /** + * An integer that describes the kind of this token. This numbering + * system is determined by JavaCCParser, and a table of these numbers is + * stored in the file ...Constants.java. + */ + public int kind; + + /** The line number of the first character of this Token. */ + public int beginLine; + /** The column number of the first character of this Token. */ + public int beginColumn; + /** The line number of the last character of this Token. */ + public int endLine; + /** The column number of the last character of this Token. */ + public int endColumn; + + /** + * The string image of the token. + */ + public String image; + + /** + * A reference to the next regular (non-special) token from the input + * stream. If this is the last token from the input stream, or if the + * token manager has not read tokens beyond this one, this field is + * set to null. This is true only if this token is also a regular + * token. Otherwise, see below for a description of the contents of + * this field. + */ + public Token next; + + /** + * This field is used to access special tokens that occur prior to this + * token, but after the immediately preceding regular (non-special) token. + * If there are no such special tokens, this field is set to null. + * When there are more than one such special token, this field refers + * to the last of these special tokens, which in turn refers to the next + * previous special token through its specialToken field, and so on + * until the first special token (whose specialToken field is null). + * The next fields of special tokens refer to other special tokens that + * immediately follow it (without an intervening regular token). If there + * is no such token, this field is null. + */ + public Token specialToken; + + /** + * An optional attribute value of the Token. + * Tokens which are not used as syntactic sugar will often contain + * meaningful values that will be used later on by the compiler or + * interpreter. This attribute value is often different from the image. + * Any subclass of Token that actually wants to return a non-null value can + * override this method as appropriate. + */ + public static Object getValue() { + return null; + } + + /** + * No-argument constructor + */ + public Token() {} + + /** + * Constructs a new token for the specified Image. + */ + public Token(int kind) + { + this(kind, null); + } + + /** + * Constructs a new token for the specified Image and Kind. + */ + public Token(int kind, String image) + { + this.kind = kind; + this.image = image; + } + + /** + * Returns the image. + */ + @Override +public String toString() + { + return image; + } + + /** + * Returns a new Token object, by default. However, if you want, you + * can create and return subclass objects based on the value of ofKind. + * Simply add the cases to the switch for all those special cases. + * For example, if you have a subclass of Token called IDToken that + * you want to create if ofKind is ID, simply add something like : + * + * case MyParserConstants.ID : return new IDToken(ofKind, image); + * + * to the following switch statement. Then you can cast matchedToken + * variable to the appropriate type and use sit in your lexical actions. + */ + public static Token newToken(int ofKind, String image) + { + switch(ofKind) + { + default : return new Token(ofKind, image); + } + } + + public static Token newToken(int ofKind) + { + return newToken(ofKind, null); + } + +} +/* JavaCC - OriginalChecksum=ad9059036c2df112e5851986a59467a6 (do not edit this line) */ diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/TokenMgrError.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/TokenMgrError.java new file mode 100644 index 000000000..f7e25574c --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/TokenMgrError.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */ +/* JavaCCOptions: */ +package edu.utah.ece.async.lema.verification.lpn; + +/** Token Manager Error. + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class TokenMgrError extends Error +{ + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /* + * Ordinals for various reasons why an Error of this type can be thrown. + */ + + /** + * Lexical error occurred. + */ + static final int LEXICAL_ERROR = 0; + + /** + * An attempt was made to create a second instance of a static token manager. + */ + static final int STATIC_LEXER_ERROR = 1; + + /** + * Tried to change to an invalid lexical state. + */ + static final int INVALID_LEXICAL_STATE = 2; + + /** + * Detected (and bailed out of) an infinite loop in the token manager. + */ + static final int LOOP_DETECTED = 3; + + /** + * Indicates the reason why the exception is thrown. It will have + * one of the above 4 values. + */ + int errorCode; + + /** + * Replaces unprintable characters by their escaped (or unicode escaped) + * equivalents in the given string + */ + protected static final String addEscapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case 0 : + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); + } + + /** + * Returns a detailed message for the Error when it is thrown by the + * token manager to indicate a lexical error. + * Parameters : + * EOFSeen : indicates if EOF caused the lexical error + * curLexState : lexical state in which this error occurred + * errorLine : line number when the error occurred + * errorColumn : column number when the error occurred + * errorAfter : prefix that was seen before this error occurred + * curchar : the offending character + * Note: You can customize the lexical error message by modifying this method. + */ + protected static String LexicalError(boolean EOFSeen, int errorLine, int errorColumn, String errorAfter, char curChar) { + return("Lexical error at line " + + errorLine + ", column " + + errorColumn + ". Encountered: " + + (EOFSeen ? " " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") + + "after : \"" + addEscapes(errorAfter) + "\""); + } + + /** + * You can also modify the body of this method to customize your error messages. + * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not + * of end-users concern, so you can return something like : + * + * "Internal Error : Please file a bug report .... " + * + * from this method for such cases in the release version of your parser. + */ + @Override +public String getMessage() { + return super.getMessage(); + } + + /* + * Constructors of various flavors follow. + */ + + /** No arg constructor. */ + public TokenMgrError() { + } + + /** Constructor with message and reason. */ + public TokenMgrError(String message, int reason) { + super(message); + errorCode = reason; + } + + /** Full Constructor. */ + public TokenMgrError(boolean EOFSeen, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) { + this(LexicalError(EOFSeen, errorLine, errorColumn, errorAfter, curChar), reason); + } +} +/* JavaCC - OriginalChecksum=ce3529e97c9e8097235dbae4de0edb3c (do not edit this line) */ diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Transition.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Transition.java new file mode 100644 index 000000000..ed422aef0 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Transition.java @@ -0,0 +1,1034 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Observable; +import java.util.Set; + +import edu.utah.ece.async.ibiosim.dataModels.util.Message; +import edu.utah.ece.async.lema.verification.platu.main.Options; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Transition extends Observable { + + private String label; + + private boolean fail = false; + + private boolean persistent = false; + + private String enabling; + + private ExprTree enablingTree; + + private String delay; + + private ExprTree delayTree; + + private String priority; + + private ExprTree priorityTree; + + private ArrayList preset; + + private ArrayList postset; + + private HashMap boolAssignments; + + private HashMap boolAssignTrees; + + private HashMap intAssignments; + + private HashMap intAssignTrees; + + private HashMap contAssignments; + + private HashMap contAssignTrees; + + private HashMap rateAssignments; + + private HashMap rateAssignTrees; + + private LPN lhpn; + + private int index; + + private final Message message = new Message(); + + /** + * List of LPNs that can be affected by firing this transition. + */ + private List dstLpnList = new ArrayList(); + + /** + * This field variable collects each product term of the transition's enabling condition. + * It is initialized when buildConjunctsOfEnabling is called. + */ + private ArrayList conjuncts; + +// public Transition(String name, ArrayList variables, LhpnFile lhpn) { +// this.name = name; +// this.lhpn = lhpn; +// preset = new ArrayList(); +// postset = new ArrayList(); +// boolAssignments = new HashMap(); +// boolAssignTrees = new HashMap(); +// intAssignments = new HashMap(); +// intAssignTrees = new HashMap(); +// contAssignments = new HashMap(); +// contAssignTrees = new HashMap(); +// rateAssignments = new HashMap(); +// rateAssignTrees = new HashMap(); +// } + + public Transition(String name, int index, LPN lhpn) { + this.label = name; + this.lhpn = lhpn; + this.index = index; + //this.local = local; + preset = new ArrayList(); + postset = new ArrayList(); + boolAssignments = new HashMap(); + boolAssignTrees = new HashMap(); + intAssignments = new HashMap(); + intAssignTrees = new HashMap(); + contAssignments = new HashMap(); + contAssignTrees = new HashMap(); + rateAssignments = new HashMap(); + rateAssignTrees = new HashMap(); + } + + public Transition() { + preset = new ArrayList(); + postset = new ArrayList(); + boolAssignments = new HashMap(); + boolAssignTrees = new HashMap(); + intAssignments = new HashMap(); + intAssignTrees = new HashMap(); + contAssignments = new HashMap(); + contAssignTrees = new HashMap(); + rateAssignments = new HashMap(); + rateAssignTrees = new HashMap(); + } + + public void addPostset(Place place) { + if (postset != null) + postset.add(place); + else { + postset = new ArrayList(); + postset.add(place); + } + } + + public void addPreset(Place place) { + if (preset != null) + preset.add(place); + else { + preset = new ArrayList(); + preset.add(place); + } + } + + public boolean addEnabling(String newEnab) { + boolean retVal = false; + if (newEnab == null) { + return false; + } + if (newEnab.equals("")) { + enabling = ""; + enablingTree = new ExprTree(); + retVal = true; + } + ExprTree expr = new ExprTree(lhpn); + if (!newEnab.equals("")) { + try { + expr.token = expr.intexpr_gettok(newEnab); + expr.intexpr_L(newEnab); + enablingTree = expr; + enabling = newEnab; + return true; + } catch (IllegalArgumentException e) { + message.setErrorDialog("Parse Error in Property", String.format("Error parsing %s\n",newEnab)+e.getMessage()); + this.notifyObservers(message); + return false; + } + } + return retVal; + } + + public void addEnablingWithoutLPN(ExprTree newEnab) { + if (newEnab != null) { + enablingTree = newEnab; + enabling = newEnab.toString(); + } + } + + public boolean addIntAssign(String variable, String assignment) { + ExprTree expr = new ExprTree(lhpn); + try { + expr.token = expr.intexpr_gettok(assignment); + expr.intexpr_L(assignment); + intAssignTrees.put(variable, expr); + intAssignments.put(variable, assignment); + return true; + } catch (IllegalArgumentException e) { + message.setErrorDialog("Parse Error in Property", String.format("Error parsing %s\n",assignment)+e.getMessage()); + this.notifyObservers(message); + return false; + } + } + + public void addIntAssign(String variable, ExprTree assignment) { + if (intAssignTrees == null && intAssignments == null) { + intAssignTrees = new HashMap(); + intAssignments = new HashMap(); + intAssignTrees.put(variable, assignment); + intAssignments.put(variable, assignment.toString()); + } + else if (intAssignTrees == null && intAssignments != null){ + intAssignTrees = new HashMap(); + intAssignTrees.put(variable, assignment); + intAssignments.put(variable, assignment.toString()); + } + else if (intAssignments == null && intAssignTrees != null) { + intAssignments = new HashMap(); + intAssignTrees.put(variable, assignment); + intAssignments.put(variable, assignment.toString()); + } + else { + intAssignTrees.put(variable, assignment); + intAssignments.put(variable, assignment.toString()); + } + } + + public boolean addContAssign(String variable, String assignment) { + ExprTree expr = new ExprTree(lhpn); + try { + expr.token = expr.intexpr_gettok(assignment); + expr.intexpr_L(assignment); + contAssignTrees.put(variable, expr); + contAssignments.put(variable, assignment); + return true; + } catch (IllegalArgumentException e) { + message.setErrorDialog("Parse Error in Property", String.format("Error parsing %s\n",assignment)+e.getMessage()); + this.notifyObservers(message); + return false; + } + } + + public boolean addRateAssign(String variable, String assignment) { + ExprTree expr = new ExprTree(lhpn); + try { + expr.token = expr.intexpr_gettok(assignment); + expr.intexpr_L(assignment); + rateAssignTrees.put(variable, expr); + rateAssignments.put(variable, assignment); + return true; + } catch (IllegalArgumentException e) { + message.setErrorDialog("Parse Error in Property", String.format("Error parsing %s\n",assignment)+e.getMessage()); + this.notifyObservers(message); + return false; + } + } + + public boolean addDelay(String delay) { + if (delay.equals("")) { + this.delay = null; + delayTree = null; + return true; + } + if (delay.matches("\\d+?,\\d+?")) { + delay = "uniform(" + delay + ")"; + } + ExprTree expr = new ExprTree(lhpn); + try { + expr.token = expr.intexpr_gettok(delay); + expr.intexpr_L(delay); + delayTree = expr; + this.delay = delay; + return true; + } catch (IllegalArgumentException e) { + message.setErrorDialog("Parse Error in Property", String.format("Error parsing %s\n",delay)+e.getMessage()); + this.notifyObservers(message); + return false; + } + } + + public boolean addPriority(String priority) { + if (priority.equals("")) { + this.priority = null; + priorityTree = null; + return true; + } + ExprTree expr = new ExprTree(lhpn); + try { + expr.token = expr.intexpr_gettok(priority); + expr.intexpr_L(priority); + priorityTree = expr; + this.priority = priority; + return true; + } catch (IllegalArgumentException e) { + message.setErrorDialog("Parse Error in Property", String.format("Error parsing %s\n",priority)+e.getMessage()); + this.notifyObservers(message); + return false; + } + } + + public boolean addBoolAssign(String variable, String assignment) { + ExprTree expr = new ExprTree(lhpn); + try { + expr.token = expr.intexpr_gettok(assignment); + expr.intexpr_L(assignment); + boolAssignTrees.put(variable, expr); + boolAssignments.put(variable, assignment); + return true; + } catch (IllegalArgumentException e) { + message.setErrorDialog("Parse Error in Property", String.format("Error parsing %s\n",assignment)+e.getMessage()); + this.notifyObservers(message); + return false; + } + } + + public void setName(String newName) { + this.label = newName; + } + + public void setFail(boolean fail) { + this.fail = fail; + } + + public void setIndex(int idx) { + this.index = idx; + } + + public void setPersistent(boolean persistent) { + this.persistent = persistent; + } + + public boolean isFail() { + return fail; + } + + public boolean isPersistent() { + return persistent; + } + + public boolean isConnected() { + return (preset.size() > 0 || postset.size() > 0); + } + + public boolean isInteresting(ArrayList visited) { + visited.add(this); + if (boolAssignments.size() > 0 || intAssignments.size() > 0 + || contAssignments.size() > 0 || rateAssignments.size() > 0 + || fail) { + return true; + } + for (Place p : postset) { + for (Transition t : p.getPostset()) { + if (visited.contains(t)) { + continue; + } + if (t.isInteresting(visited)) { + return true; + } + } + } + return false; + } + + /** + * Check if this transition shares a preset place with at least one other transition. + * @return true if it does + * + */ + public boolean hasConflict() { + for (Place p : getPreset()) { + for (Transition t : p.getPostset()) { + if (!this.toString().equals(t.toString())) { + return true; + } + } + } + return false; + } + + public int getIndex() { + return this.index; + } + + public String getLabel() { + return label; + } + + public String getDelay() { + return delay; + } + + public String getPriority() { + return priority; + } + + public ExprTree getDelayTree() { + return delayTree; + } + + public ExprTree getPriorityTree() { + return priorityTree; + } + + public String getTransitionRate() { + if (delayTree != null) { + if (delayTree.op.equals("exponential")) { + return delayTree.r1.toString(); + } + } + return null; + } + + public ExprTree getTransitionRateTree() { + if (delayTree.op.equals("exponential")) { + return delayTree.r1; + } + return null; + } + + public Place[] getPreset() { + Place[] array = new Place[preset.size()]; + int i = 0; + for (Place p : preset) { + array[i++] = p; + } + return array; + } + + public Place[] getPostset() { + Place[] array = new Place[postset.size()]; + int i = 0; + for (Place p : postset) { + array[i++] = p; + } + return array; + } + + public Transition[] getConflictSet() { + ArrayList conflictSet = new ArrayList(); + for (Place p : getPreset()) { + for (Transition t : p.getPostset()) { + if (!this.toString().equals(t.toString())) { + conflictSet.add(t); + } + } + } + Transition[] returnSet = new Transition[conflictSet.size()]; + int i = 0; + for (Transition t : conflictSet) { + returnSet[i] = t; + i++; + } + return returnSet; + } + + public Set getConflictSetTransNames() { + Set conflictSet = new HashSet(); + for (Place p : getPreset()) { + for (Transition t : p.getPostset()) { + if (!this.toString().equals(t.toString())) { + conflictSet.add(t.getLabel()); + } + } + } + return conflictSet; + } + + public HashSet getConflictSetTransIndices() { + HashSet conflictSet = new HashSet(); + for (Place p : getPreset()) { + for (Transition t : p.getPostset()) { + if (!this.toString().equals(t.toString())) { + conflictSet.add(t.getIndex()); + } + } + } + return conflictSet; + } + + + public String getEnabling() { + return enabling; + } + + public ExprTree getEnablingTree() { + return enablingTree; + } + + public HashMap getAssignments() { + HashMap assignments = new HashMap(); + assignments.putAll(boolAssignments); + assignments.putAll(intAssignments); + assignments.putAll(contAssignments); + for (String var : rateAssignments.keySet()) { + if (assignments.containsKey(var)) { + assignments.put(var + "_rate", rateAssignments.get(var)); + } else { + assignments.put(var, rateAssignments.get(var)); + } + } + return assignments; + } + + public HashMap getAssignTrees() { + HashMap assignments = new HashMap(); + assignments.putAll(boolAssignTrees); + assignments.putAll(intAssignTrees); + assignments.putAll(contAssignTrees); + for (String var : rateAssignments.keySet()) { + if (assignments.containsKey(var)) { + assignments.put(var + "_rate", rateAssignTrees.get(var)); + } else { + assignments.put(var, rateAssignTrees.get(var)); + } + } + return assignments; + } + + public ExprTree getAssignTree(String var) { + if (boolAssignTrees.containsKey(var)) { + return getBoolAssignTree(var); + } + if (intAssignTrees.containsKey(var)) { + return getIntAssignTree(var); + } + if (contAssignTrees.containsKey(var)) { + return getContAssignTree(var); + } + if (rateAssignTrees.containsKey(var)) { + return getRateAssignTree(var); + } + if (var.split("\\s").length > 1) { + return getRateAssignTree(var.split("\\s")[0]); + } + return null; + } + + public HashMap getContAssignments() { + return contAssignments; + } + + public HashMap getContAssignTrees() { + return contAssignTrees; + } + + public String getContAssignment(String variable) { + return contAssignments.get(variable); + } + + public ExprTree getContAssignTree(String variable) { + return contAssignTrees.get(variable); + } + + public HashMap getIntAssignments() { + return intAssignments; + } + + public HashMap getIntAssignTrees() { + return intAssignTrees; + } + + public String getIntAssignment(String variable) { + return intAssignments.get(variable); + } + + public ExprTree getIntAssignTree(String variable) { + return intAssignTrees.get(variable); + } + + public HashMap getRateAssignments() { + return rateAssignments; + } + + public HashMap getRateAssignTrees() { + return rateAssignTrees; + } + + public String getRateAssignment(String variable) { + return rateAssignments.get(variable); + } + + public ExprTree getRateAssignTree(String variable) { + return rateAssignTrees.get(variable); + } + + public HashMap getBoolAssignments() { + return boolAssignments; + } + + public HashMap getBoolAssignTrees() { + return boolAssignTrees; + } + + public String getBoolAssignment(String variable) { + return boolAssignments.get(variable); + } + + public ExprTree getBoolAssignTree(String variable) { + return boolAssignTrees.get(variable); + } + + public void renamePlace(Place oldPlace, Place newPlace) { + if (preset.contains(oldPlace)) { + preset.add(newPlace); + preset.remove(oldPlace); + } + if (postset.contains(oldPlace)) { + postset.add(newPlace); + postset.remove(oldPlace); + } + } + + public void removeEnabling() { + enabling = null; + enablingTree = null; + } + + public void removePreset(Place place) { + preset.remove(place); + } + + public void removePostset(Place place) { + postset.remove(place); + } + + public void removeAllAssign() { + boolAssignments.clear(); + contAssignments.clear(); + rateAssignments.clear(); + intAssignments.clear(); + } + + public void removeAssignment(String variable) { + if (contAssignments.containsKey(variable)) { + removeContAssign(variable); + } + if (rateAssignments.containsKey(variable)) { + removeRateAssign(variable); + } + if (intAssignments.containsKey(variable)) { + removeIntAssign(variable); + } + if (boolAssignments.containsKey(variable)) { + removeBoolAssign(variable); + } + if (variable.split("\\s").length > 1) { + removeRateAssign(variable.split("\\s")[0]); + } + } + + public void removeBoolAssign(String variable) { + boolAssignments.remove(variable); + boolAssignTrees.remove(variable); + } + + public void removeContAssign(String variable) { + contAssignments.remove(variable); + contAssignTrees.remove(variable); + } + + public void removeRateAssign(String variable) { + rateAssignments.remove(variable); + rateAssignTrees.remove(variable); + } + + public void removeIntAssign(String variable) { + intAssignments.remove(variable); + intAssignTrees.remove(variable); + } + + public boolean containsDelay() { + return ((delay != null) && !delay.equals("")); + } + + public boolean containsEnabling() { + return ((enabling != null) && !enabling.equals("")); + } + + public boolean containsPriority() { + return ((priority != null) && !priority.equals("")); + } + + public boolean containsPreset(String name) { + return preset.contains(name); + } + + public boolean containsPostset(String name) { + return postset.contains(name); + } + + public boolean containsAssignment() { + return (boolAssignments.size() > 0 || intAssignments.size() > 0 + || contAssignments.size() > 0 || rateAssignments.size() > 0); + } + + public boolean containsBooleanAssignment() { + return boolAssignments.size() > 0; + } + + public boolean containsIntegerAssignment() { + return intAssignments.size() > 0; + } + + public boolean containsContinuousAssignment() { + return contAssignments.size() > 0; + } + + public boolean containsRateAssignment() { + return rateAssignments.size() > 0; + } + + public boolean containsAssignment(String var) { + if (boolAssignments.containsKey(var)) { + return true; + } + if (intAssignments.containsKey(var)) { + return true; + } + if (contAssignments.containsKey(var)) { + return true; + } + if (rateAssignments.containsKey(var)) { + return true; + } + return false; + } + + public boolean simplifyExpr(boolean change) { + if (enablingTree != null) { + if (!enabling.equals(enablingTree.toString("LHPN"))) { + change = true; + } + String newEnab = enablingTree.toString("LHPN"); + addEnabling(newEnab); + } + if (delayTree != null) { + if (!delay.equals(delayTree.toString("LHPN"))) { + change = true; + } + String newDelay = delayTree.toString("LHPN"); + addDelay(newDelay); + } + for (String var : boolAssignTrees.keySet()) { + if (!boolAssignments.get(var).equals( + boolAssignTrees.get(var).toString("boolean", "LHPN"))) { + change = true; + } + boolAssignments.put(var, boolAssignTrees.get(var).toString( + "boolean", "LHPN")); + } + for (String var : intAssignTrees.keySet()) { + if (!intAssignments.get(var).equals( + intAssignTrees.get(var).toString("integer", "LHPN"))) { + change = true; + } + intAssignments.put(var, intAssignTrees.get(var).toString("integer", + "LHPN")); + } + for (String var : contAssignTrees.keySet()) { + if (!contAssignments.get(var).equals( + contAssignTrees.get(var).toString("continuous", "LHPN"))) { + change = true; + } + contAssignments.put(var, contAssignTrees.get(var).toString( + "continuous", "LHPN")); + } + for (String var : rateAssignTrees.keySet()) { + if (!rateAssignments.get(var).equals( + rateAssignTrees.get(var).toString("continuous", "LHPN"))) { + change = true; + } + rateAssignments.put(var, rateAssignTrees.get(var).toString( + "continuous", "LHPN")); + } + return change; + } + + public boolean minimizeUniforms(boolean change) { + if (enablingTree != null) { + if (!enabling.equals(enablingTree.minimizeUniforms().toString( + "LHPN"))) { + change = true; + } + enabling = enablingTree.minimizeUniforms().toString("LHPN"); + } + if (delayTree != null) { + if (!delay.equals(delayTree.minimizeUniforms().toString("LHPN"))) { + change = true; + } + delay = delayTree.minimizeUniforms().toString("LHPN"); + } + for (String var : boolAssignTrees.keySet()) { + if (!boolAssignments.get(var).equals( + boolAssignTrees.get(var).minimizeUniforms().toString( + "boolean", "LHPN"))) { + change = true; + } + boolAssignments.put(var, boolAssignTrees.get(var) + .minimizeUniforms().toString("boolean", "LHPN")); + } + for (String var : intAssignTrees.keySet()) { + if (!intAssignments.get(var).equals( + intAssignTrees.get(var).minimizeUniforms().toString( + "integer", "LHPN"))) { + change = true; + } + intAssignments.put(var, intAssignTrees.get(var).minimizeUniforms() + .toString("integer", "LHPN")); + } + for (String var : contAssignTrees.keySet()) { + if (!contAssignments.get(var).equals( + contAssignTrees.get(var).minimizeUniforms().toString( + "continuous", "LHPN"))) { + change = true; + } + contAssignments.put(var, contAssignTrees.get(var) + .minimizeUniforms().toString("continuous", "LHPN")); + } + for (String var : rateAssignTrees.keySet()) { + if (!rateAssignments.get(var).equals( + rateAssignTrees.get(var).minimizeUniforms().toString( + "continuous", "LHPN"))) { + change = true; + } + rateAssignments.put(var, rateAssignTrees.get(var) + .minimizeUniforms().toString("continuous", "LHPN")); + } + return change; + } + + @Override + public String toString() { + return "Transition [label=" + label + ", lhpn=" + lhpn.getLabel() + ", tranIndex=" + + index + "]"; + } + + public void changeName(String newName) { + label = newName; + } + + /** + * @return LPN object containing this LPN transition. + */ + public LPN getLpn() { + return lhpn; + } + + /** + * @param lpn - Associated LPN containing this LPN transition. + */ + public void setLpn(LPN lpn) { + this.lhpn = lpn; + } + + public boolean isLocal() { + // Returns true if LPNTran only modifies internal variables. + boolean isLocal = true; + for (String assignVar : this.getAssignments().keySet()) { + if (!this.getLpn().getAllInternals().keySet().contains(assignVar)) { + isLocal = false; + break; + } + } + return isLocal; + } + +// public void setLocal(boolean local) { +// this.local = local; +// } + + public List getDstLpnList(){ + return this.dstLpnList; + } + +// public void addDstLpn(LhpnFile lpn){ +// this.dstLpnList.add(lpn); +// } + + public String getFullLabel() { + return this.getLabel() + "(" + this.getLpn().getLabel() + ")"; + } + + /** + * Check if firing 'fired_transition' causes a disabling error. + * @param current_enabled_transitions + * @param next_enabled_transitions + * @return + */ + public Transition disablingError(final LinkedList current_enabled_transitions, + LinkedList next_enabled_transitions) { + if (current_enabled_transitions == null || current_enabled_transitions.size()==0) + return null; + for(Transition curTran : current_enabled_transitions) { + if (curTran == this) + continue; + boolean disabled = true; + if (next_enabled_transitions != null && next_enabled_transitions.size()!=0) { + for(Transition nextTran : next_enabled_transitions) { + if(curTran == nextTran) { + disabled = false; + break; + } + } + } + if (disabled == true) { + Place[] preset1 = this.getPreset(); + Place[] preset2 = curTran.getPreset(); + Boolean share=false; + for (int i=0; i < preset1.length && !share; i++) { + for (int j=0; j < preset2.length && !share; j++) { + if (preset1[i].getName().equals(preset2[j].getName())) share=true; + } + } + if (!share) return curTran; +// if(this.sharePreSet(curTran) == false) +// return curTran; + /* + for (Iterator confIter = this.getConflictSetTransNames().iterator(); confIter.hasNext();) { + String tran = confIter.next(); + if (curTran.getConflictSetTransNames().contains(tran)) + return curTran; + } + */ + } + } + return null; + } + + /** + * If this transition's assignment can cause curTran's enabling condition to become FALSE, + * or it appears at either the right or left hand side of curTran's assignment, + * then it is added to the dstLpnList for this transition. + * @param curLPN + */ + public void setDstLpnList(LPN curLPN) { + for (Transition curTran : curLPN.getAllTransitions()) { + ExprTree curTranEnablingTree = curTran.getEnablingTree(); + if (curTranEnablingTree != null + && (curTranEnablingTree.getChange(this.getAssignments())=='F' + || curTranEnablingTree.getChange(this.getAssignments())=='f' + || curTranEnablingTree.getChange(this.getAssignments())=='X')) { + this.dstLpnList.add(curLPN); + return; + } + for (String v : this.getAssignTrees().keySet()) { + for (ExprTree curTranAssignTree : curTran.getAssignTrees().values()) { + if (curTranAssignTree != null && curTranAssignTree.containsVar(v)) { + this.dstLpnList.add(curLPN); + return; + } + } + } + for (String v1 : this.getAssignTrees().keySet()) { + for (String v2 : curTran.getAssignTrees().keySet()) { + if (v1.equals(v2) && !this.getAssignTree(v1).equals(curTran.getAssignTree(v2))) { + this.dstLpnList.add(curLPN); + return; + } + } + } + if (Options.getMarkovianModelFlag()) { // && !Options.getTranRatePorDef().toLowerCase().equals("none")) { + ExprTree curTranDelayTree = curTran.getDelayTree(); + if (curTranDelayTree != null) { + for (String var : this.getAssignments().keySet()) { + if (curTranDelayTree.containsVar(var)) { + this.dstLpnList.add(curLPN); + return; + } + } + } + } + } + } + + /** + * This method takes the enabling condition of a transition (in the product-of-sums), and break the conjunction into conjuncts. + * @param term + */ + public void buildConjunctsOfEnabling(ExprTree term) { + if (conjuncts == null) + conjuncts = new ArrayList(); + if (term.getOp().equals("&&")){ + buildConjunctsOfEnabling(term.getLeftChild()); + buildConjunctsOfEnabling(term.getRightChild()); + } + else { + conjuncts.add(term); + } + } + + public ArrayList getConjunctsOfEnabling() { + return conjuncts; + } + /* Maybe copy method below is not needed. + public Transition copy(HashMap variables){ + return new Transition(this.name, this.index, this.preset, this.postset, this.enablingGuard.copy(variables), + this.assignments.copy(variables), this.delayLB, this.delayUB, this.local); + } + */ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (fail ? 1231 : 1237); + result = prime * result + ((label == null) ? 0 : label.hashCode()); + result = prime * result + ((lhpn == null) ? 0 : lhpn.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Transition other = (Transition) obj; + if (fail != other.fail) + return false; + if (label == null) { + if (other.label != null) + return false; + } else if (!label.equals(other.label)) + return false; + if (lhpn == null) { + if (other.lhpn != null) + return false; + } else if (!lhpn.equals(other.lhpn)) + return false; + return true; + } + +} \ No newline at end of file diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Translator.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Translator.java new file mode 100644 index 000000000..ce6815abb --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Translator.java @@ -0,0 +1,1906 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn; + +import java.io.FileNotFoundException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Observable; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.xml.stream.XMLStreamException; + +import org.sbml.jsbml.Compartment; +import org.sbml.jsbml.Constraint; +import org.sbml.jsbml.ASTNode; +import org.sbml.jsbml.AssignmentRule; +import org.sbml.jsbml.Event; +import org.sbml.jsbml.EventAssignment; +import org.sbml.jsbml.FunctionDefinition; +import org.sbml.jsbml.InitialAssignment; +import org.sbml.jsbml.KineticLaw; +import org.sbml.jsbml.Model; +import org.sbml.jsbml.ModifierSpeciesReference; +import org.sbml.jsbml.Parameter; +import org.sbml.jsbml.RateRule; +import org.sbml.jsbml.Reaction; +import org.sbml.jsbml.SBMLDocument; +import org.sbml.jsbml.SBMLException; +import org.sbml.jsbml.SBMLWriter; +import org.sbml.jsbml.Species; +import org.sbml.jsbml.SpeciesReference; +import org.sbml.jsbml.Trigger; +import org.sbml.jsbml.text.parser.FormulaParserLL3; +import org.sbml.jsbml.text.parser.IFormulaParser; +import org.sbml.jsbml.text.parser.ParseException; + +import edu.utah.ece.async.ibiosim.dataModels.biomodel.util.SBMLutilities; +import edu.utah.ece.async.ibiosim.dataModels.util.GlobalConstants; +import edu.utah.ece.async.ibiosim.dataModels.util.exceptions.BioSimException; +import edu.utah.ece.async.lema.verification.lpn.ExprTree; + +/** + * This class converts a lph file to a sbml file + * + * @author Zhen Zhang + * + */ +public class Translator extends Observable { + private String filename; + private SBMLDocument document; + public static boolean isSteadyState = false; + public static boolean isHSF = false; + + public void oldBuildTemplate(String lhpnFilename, String property) throws BioSimException { + this.filename = lhpnFilename.replace(".lpn", ".xml"); + // load lhpn file + LPN lhpn = new LPN(); + lhpn.load(lhpnFilename); + + // create sbml file + //document = new SBMLDocument(BioSim.SBML_LEVEL, BioSim.SBML_VERSION); + document = new SBMLDocument(3,1); + Model m = document.createModel(filename.replace(".xml", "")); + Compartment c = m.createCompartment(); + c.setId("default"); + c.setSize(1.0); + c.setConstant(true); + c.setSpatialDimensions(3); + + // Create bitwise operators for sbml + createFunction(m, "rate", "Rate", "lambda(a,a)"); + createFunction(m, "BIT", "bit selection", "lambda(a,b,a*b)"); + createFunction(m, "BITAND", "Bitwise AND", "lambda(a,b,a*b)"); + createFunction(m, "BITOR", "Bitwise OR", "lambda(a,b,a*b)"); + createFunction(m, "BITNOT", "Bitwise NOT", "lambda(a,b,a*b)"); + createFunction(m, "BITXOR", "Bitwise XOR", "lambda(a,b,a*b)"); + createFunction(m, "mod", "Modular", "lambda(a,b,a-floor(a/b)*b)"); + //createFunction(m, "and", "Logical AND", "lambda(a,b,a*b)"); + createFunction(m, "uniform", "Uniform distribution", "lambda(a,b,(a+b)/2)"); + createFunction(m, "normal", "Normal distribution", "lambda(m,s,m)"); + createFunction(m, "exponential", "Exponential distribution", "lambda(l,1/l)"); + createFunction(m, "gamma", "Gamma distribution", "lambda(a,b,a*b)"); + createFunction(m, "lognormal", "Lognormal distribution", "lambda(z,s,exp(z+s^2/2))"); + createFunction(m, "chisq", "Chi-squared distribution", "lambda(nu,nu)"); + createFunction(m, "laplace", "Laplace distribution", "lambda(a,0)"); + createFunction(m, "cauchy", "Cauchy distribution", "lambda(a,a)"); + createFunction(m, "rayleigh", "Rayleigh distribution", "lambda(s,s*sqrt(pi/2))"); + createFunction(m, "poisson", "Poisson distribution", "lambda(mu,mu)"); + createFunction(m, "binomial", "Binomial distribution", "lambda(p,n,p*n)"); + createFunction(m, "bernoulli", "Bernoulli distribution", "lambda(p,p)"); + + // translate from lhpn to sbml + // ----variables -> parameters----- + for (String v: lhpn.getVariables()){ + if (v != null){ + String initVal = lhpn.getInitialVal(v); + if (lhpn.isContinuous(v) || lhpn.isInteger(v)){ + Parameter var = m.createParameter(); + var.setConstant(false); + var.setId(v); + Pattern initVarIsIntPattern = Pattern.compile(Int); + Matcher initVarIsIntMatcher = initVarIsIntPattern.matcher(initVal); + boolean initVarIsInt = initVarIsIntMatcher.matches(); + Pattern initVarIsRangePattern = Pattern.compile(Range); + Matcher initVarIsRangeMatcher = initVarIsRangePattern.matcher(initVal); + boolean initVarIsRange = initVarIsRangeMatcher.matches(); + Pattern initRangeBoundPattern = Pattern.compile(Range); + Matcher initRangeBoundMatcher = initRangeBoundPattern.matcher(initVal); + boolean initVarRangeFound = initRangeBoundMatcher.find(); + if (initVarIsInt && !initVarIsRange) { + double initValDouble = Double.parseDouble(initVal); + var.setValue(initValDouble); + } + if (!initVarIsInt && initVarIsRange && initVarRangeFound) { + var.setValue(0); + InitialAssignment initAssign = m.createInitialAssignment(); + initAssign.setVariable(var.getId()); + String initVarAssignRHS = "uniform("; + for (int i=1; i<=initRangeBoundMatcher.groupCount();i++) { + initVarAssignRHS = initVarAssignRHS + initRangeBoundMatcher.group(i); + //initAssignRHS = initAssignRHS + initRangeBoundMatcher.group(i); + if (i==1) + initVarAssignRHS = initVarAssignRHS + ","; + } + initVarAssignRHS = initVarAssignRHS + ")"; + initAssign.setMath(SBMLutilities.myParseFormula(initVarAssignRHS)); + } + // For each continuous variable v, create rate rule dv/dt and set its initial value to lhpn.getInitialRate(v). + if (lhpn.isContinuous(v) && !lhpn.isInput(v)){ + Parameter rateVar = m.createParameter(); + rateVar.setConstant(false); + rateVar.setId(v + "_rate"); + RateRule rateRule = m.createRateRule(); + rateRule.setVariable(v); + rateRule.setMath(SBMLutilities.myParseFormula(rateVar.getId())); + String initRate= lhpn.getInitialRate(v); + boolean initRateIsInt = Pattern.matches(Int, initRate); + boolean initRateIsRange = Pattern.matches(Range, initRate); + Pattern initRateRangePattern = Pattern.compile(Range); + Matcher initRateRangeMatcher = initRateRangePattern.matcher(initRate); + boolean initRateRangeFound = initRateRangeMatcher.find(); + + if (initRateIsInt && !initRateIsRange) { + double initRateDouble = Double.parseDouble(initRate); + rateVar.setValue(initRateDouble); + } + if (!initRateIsInt && initRateIsRange && initRateRangeFound) { + rateVar.setValue(0); + InitialAssignment initAssign = m.createInitialAssignment(); + initAssign.setVariable(rateVar.getId()); + initAssign.setMath(SBMLutilities.myParseFormula(initRate)); + String initRateAssignRHS = "uniform("; + for (int i=1; i<=initRateRangeMatcher.groupCount();i++) { + initRateAssignRHS = initRateAssignRHS + initRateRangeMatcher.group(i); + if (i==1) + initRateAssignRHS = initRateAssignRHS + ","; + } + initRateAssignRHS = initRateAssignRHS + ")"; + initAssign.setMath(SBMLutilities.myParseFormula(initRateAssignRHS)); + } + } + } + else // boolean variable + { + Parameter p = m.createParameter(); + p.setConstant(false); + p.setId(v); + String initValue = lhpn.getInitialVal(v); +// System.out.println(v + "=" + initValue); + // check initValue type; if boolean, set parameter value as 0 or 1. + if (initValue.equals("true")){ + p.setValue(1); + } + else if (initValue.equals("false")){ + p.setValue(0); + } + else if (initValue.equals("unknown")){ + p.setValue(0); + } + else { +// double initVal_dbl = Double.parseDouble(initValue); +// p.setValue(initVal_dbl); + System.out.println("It should be a boolean variable."); + System.exit(0); + } + } + } + } + + // ----places -> species----- + for (String p: lhpn.getPlaceList()){ + Boolean initMarking = lhpn.getPlace(p).isMarked(); +// System.out.println(p + "=" + initMarking); + Species sp = m.createSpecies(); + sp.setId(p); + sp.setCompartment("default"); + sp.setBoundaryCondition(false); + sp.setConstant(false); + sp.setHasOnlySubstanceUnits(false); + if (initMarking){ + sp.setInitialAmount(1); + } + else { + sp.setInitialAmount(0); + } + sp.setUnits(""); + } + + // ----convert transitions ----- + // if transition rate is not null, use reaction and event; + // else use event only + int counter = lhpn.getTransitionList().length - 1; + for (String t : lhpn.getTransitionList()) { + if(lhpn.getTransition(t).getTransitionRate()!=null){ + Species spT = m.createSpecies(); + spT.setId("Event_"+t); + spT.setCompartment("default"); + spT.setBoundaryCondition(false); + spT.setConstant(false); + spT.setHasOnlySubstanceUnits(false); + spT.setInitialAmount(0); + spT.setUnits(""); + + Reaction r = m.createReaction(); + r.setReversible(false); + r.setFast(false); + r.setId("r" + counter); + + //test En(t) + String EnablingTestNull = lhpn.getTransition(t).getEnabling(); + String Enabling; + String EnablingBool = null; + if (EnablingTestNull == null){ + EnablingBool = "true"; + Enabling = "1"; // Enabling is true + } + else { + EnablingBool = lhpn.getEnablingTree(t).toString("SBML"); + Enabling = "piecewise(1, " + EnablingBool + ", 0)"; + } + + //test Preset(t) + String CheckPreset = null; + int indexPreset = 0; + + // Check if all the presets of transition t are marked + // Transition t can fire only when all its preset are marked. + for (String x:lhpn.getPreset(t)){ + if (indexPreset == 0){ + CheckPreset = "eq(" + x + ",1)"; + } + else { + CheckPreset = "and(" + CheckPreset + "," + "eq(" + x + ",1)" + ")"; + } + indexPreset ++; + } + + String modifierStr = ""; + String reactantStr = ""; + for (String x : lhpn.getPreset(t)){ + // Is transition persistent? + if (lhpn.getTransition(t).isPersistent()){ + // transition is persistent + // Create a rule for the persistent transition t. + AssignmentRule rulePersis = m.createAssignmentRule(); + String rulePersisSpeciesStr = "rPersis_" + t + x; + // Create a parameter (id = rulePersisTriggName). + Species rulePersisSpecies = m.createSpecies(); + rulePersisSpecies.setId(rulePersisSpeciesStr); + rulePersisSpecies.setCompartment("default"); + rulePersisSpecies.setBoundaryCondition(false); + rulePersisSpecies.setConstant(false); + rulePersisSpecies.setHasOnlySubstanceUnits(false); + rulePersisSpecies.setUnits(""); + + String ruleExpBool = "or(and(" + CheckPreset + "," + EnablingBool + "), and(" + CheckPreset + "," + "eq(" + rulePersisSpeciesStr + ", 1)" +"))"; + String ruleExpReal = "piecewise(1, " + ruleExpBool + ", 0)"; + rulePersis.setVariable(rulePersisSpeciesStr); + rulePersis.setMath(SBMLutilities.myParseFormula(ruleExpReal)); + rulePersisSpecies.setInitialAmount(0); + ModifierSpeciesReference modifier = r.createModifier(); + modifier.setSpecies(rulePersisSpeciesStr); + // create the part of Kinetic law expression involving modifiers + modifierStr = modifierStr + modifier.getSpecies().toString() + "*"; + } + else { + // get the preset of a transition and set each as a reactant + SpeciesReference reactant = r.createReactant(); + reactant.setSpecies(x); + reactant.setStoichiometry(1.0); + reactant.setConstant(true); + reactantStr = reactantStr + reactant.getSpecies().toString() + "*"; + } + } + + + SpeciesReference product = r.createProduct(); + product.setSpecies(t); + product.setStoichiometry(1.0); + product.setConstant(true); + + KineticLaw rateReaction = r.createKineticLaw(); // rate of reaction + //Parameter p_local = rateReaction.createParameter(); + //p_local.setConstant(false); + //p_local.setId("rate" + counter); + // get the transition rate from LHPN + //System.out.println("transition rate = " + lhpn.getTransitionRate(t)); + //double tRate = Double.parseDouble(lhpn.getTransitionRate(t)); + //p_local.setValue(tRate); + //lhpn.getTransitionRateTree(t) + + // create exp for KineticLaw + if (lhpn.getTransition(t).isPersistent()) + rateReaction.setMath(SBMLutilities.myParseFormula("(" + modifierStr + Enabling + "*" + lhpn.getTransitionRateTree(t).toString("SBML") + ")")); + else + rateReaction.setMath(SBMLutilities.myParseFormula("(" + reactantStr + Enabling + "*" + lhpn.getTransitionRateTree(t).toString("SBML") + ")")); + + Event e = m.createEvent(); + // e.setId("event" + counter); + e.setId("Event_"+t); + Trigger trigger = e.createTrigger(); + trigger.setMath(SBMLutilities.myParseFormula("eq(" + product.getSpecies() + ",1)")); + // For persistent transition, it does not matter whether the trigger is persistent or not, because the delay is set to 0. + trigger.setPersistent(false); + e.setUseValuesFromTriggerTime(false); + trigger.setInitialValue(false); + + // t_postSet = 1 + for (String x : lhpn.getPostset(t)){ + EventAssignment assign0 = e.createEventAssignment(); + assign0.setVariable(x); + assign0.setMath(SBMLutilities.myParseFormula("1")); + // System.out.println("transition: " + t + " postset: " + x); + } + + // product = 0 + EventAssignment assign1 = e.createEventAssignment(); + assign1.setVariable(product.getSpecies()); + assign1.setMath(SBMLutilities.myParseFormula("0")); + + // if (lhpn.getTransition(t).isPersistent()){ + // // t_preSet = 0 + // for (String x : lhpn.getPreset(t)){ + // EventAssignment assign0 = e.createEventAssignment(); + // assign0.setVariable(x); + // assign0.setMath(SBMLutilities.myParseFormula("0")); + // // System.out.println("transition: " + t + " preset: " + x); + // } + // } + + // assignment + // continuous assignment + if (lhpn.getContVars(t) != null){ + for (String var : lhpn.getContVars(t)){ + if (lhpn.getContAssign(t, var) != null) { + ExprTree assignContTree = lhpn.getContAssignTree(t, var); + String assignCont = assignContTree.toString("SBML"); + // System.out.println("continuous assign: "+ assignCont); + EventAssignment assign2 = e.createEventAssignment(); + assign2.setVariable(var); + assign2.setMath(SBMLutilities.myParseFormula(assignCont)); + } + } + } + + // integer assignment + if (lhpn.getIntVars()!= null){ + for (String var : lhpn.getIntVars()){ + if (lhpn.getIntAssign(t, var) != null) { + ExprTree assignIntTree = lhpn.getIntAssignTree(t, var); + String assignInt = assignIntTree.toString("SBML"); + // System.out.println("integer assignment from LHPN: " + var + " := " + assignInt); + EventAssignment assign3 = e.createEventAssignment(); + assign3.setVariable(var); + assign3.setMath(SBMLutilities.myParseFormula(assignInt)); + } + } + } + + // boolean assignment + if (lhpn.getBooleanVars(t)!= null){ + for (String var :lhpn.getBooleanVars(t)){ + if (lhpn.getBoolAssign(t, var) != null) { + ExprTree assignBoolTree = lhpn.getBoolAssignTree(t, var); + String assignBool_tmp = assignBoolTree.toString("SBML"); + String assignBool = "piecewise(1," + assignBool_tmp + ",0)"; + // System.out.println("boolean assignment from LHPN: " + var + " := " + assignBool); + EventAssignment assign4 = e.createEventAssignment(); + assign4.setVariable(var); + assign4.setMath(SBMLutilities.myParseFormula(assignBool)); + } + } + } + + // rate assignment + if (lhpn.getRateVars(t)!= null){ + for (String var : lhpn.getRateVars(t)){ + // System.out.println("rate var: "+ var); + if (lhpn.getRateAssign(t, var) != null) { + ExprTree assignRateTree = lhpn.getRateAssignTree(t, var); + String assignRate = assignRateTree.toString("SBML"); + // System.out.println("rate assign: "+ assignRate); + + EventAssignment assign5 = e.createEventAssignment(); + assign5.setVariable(var + "_rate"); + assign5.setMath(SBMLutilities.myParseFormula(assignRate)); + } + } + } + // When translating a fail transition into an event, that event should assign to a special "fail" variable a value of 1. + // This "fail" variable should have initial value of 0. The SBML model should have a constraint "eq(fail,0)". + if (lhpn.getTransition(t).isFail()){ + Parameter failVar = m.createParameter(); + failVar.setConstant(false); + failVar.setId("failvar_" + t); + failVar.setValue(0); + EventAssignment assign6 = e.createEventAssignment(); + assign6.setVariable(failVar.getId()); + assign6.setMath(SBMLutilities.myParseFormula("1")); + Constraint failVarConstraint = m.createConstraint(); + SBMLutilities.setMetaId(failVarConstraint, "failtrans_" + t); + failVarConstraint.setMath(SBMLutilities.myParseFormula("eq(" + failVar.getId() + ", 0)")); + } + } + + else { // Transition rate = null. Only use event. Transitions only have ranges. + // System.out.println("Event Only"); + Event e = m.createEvent(); + // e.setId("event" + counter); + e.setId("Event_"+t); + Trigger trigger = e.createTrigger(); + + //trigger = CheckPreset(t) && En(t); + //test En(t) + String EnablingTestNull = lhpn.getTransition(t).getEnabling(); + String Enabling; + if (EnablingTestNull == null){ + Enabling = "true"; // Enabling is true (Boolean) + } + else { + Enabling = lhpn.getEnablingTree(t).toString("SBML"); + } + // System.out.println("Enabling = " + Enabling); + + //test Preset(t) + String CheckPreset = null; + int indexPreset = 0; + + // Check if all the presets of transition t are marked + // Transition t can fire only when all its preset are marked. + for (String x:lhpn.getPreset(t)){ + if (indexPreset == 0){ + CheckPreset = "eq(" + x + ",1)"; + } + else { + CheckPreset = "and(" + CheckPreset + "," + "eq(" + x + ",1)" + ")"; + } + indexPreset ++; + } + + // Is transition persistent? + if (!lhpn.getTransition(t).isPersistent() || (lhpn.getTransition(t).isPersistent() && !lhpn.getTransition(t).hasConflict())){ + if (!lhpn.getTransition(t).isPersistent()) { + trigger.setPersistent(false); + } + else { + trigger.setPersistent(true); + } + + trigger.setMath(SBMLutilities.myParseFormula("and(" + CheckPreset + "," + Enabling + ")")); + } + else { // transition is persistent + // Create a rule for the persistent transition t. + AssignmentRule rulePersisTrigg = m.createAssignmentRule(); + String rulePersisTriggName = GlobalConstants.TRIGGER + "_" + t; + // Create a parameter (id = rulePersisTriggName). + Parameter rulePersisParam = m.createParameter(); + rulePersisParam.setId(rulePersisTriggName); + rulePersisParam.setValue(0); + rulePersisParam.setConstant(false); + rulePersisParam.setUnits(""); + String ruleExpBool = "or(and(" + CheckPreset + "," + Enabling + "), and(" + CheckPreset + "," + "eq(" + rulePersisTriggName + ", 1)" +"))"; + String ruleExpReal = "piecewise(1, " + ruleExpBool + ", 0)"; + rulePersisTrigg.setVariable(rulePersisTriggName); + rulePersisTrigg.setMath(SBMLutilities.myParseFormula(ruleExpReal)); + trigger.setPersistent(false); + trigger.setMath(SBMLutilities.myParseFormula("eq(" + rulePersisTriggName + ", 1)")); + } + + // TriggerInitiallyFalse + // trigger.setAnnotation(""); + trigger.setInitialValue(false); + + // use values at trigger time = false + e.setUseValuesFromTriggerTime(false); + + // Priority and delay + if (lhpn.getTransition(t).getDelay()!=null) { + e.createDelay(); + String delay = lhpn.getTransition(t).getDelayTree().toString("SBML"); + e.getDelay().setMath(SBMLutilities.myParseFormula(delay)); + } + if (lhpn.getTransition(t).getPriority()!=null) { + e.createPriority(); + String priority = lhpn.getTransition(t).getPriorityTree().toString("SBML"); + e.getPriority().setMath(SBMLutilities.myParseFormula(priority)); + } + /* + if (lhpn.getTransition(t).getPriority()==null) { + if (lhpn.getTransition(t).getDelay()!=null) { + e.createDelay(); + e.getDelay().setMath(SBMLutilities.myParseFormula(lhpn.getTransition(t).getDelay())); + } + } + else { + if (lhpn.getTransition(t).getDelay()!=null) { + e.createDelay(); + e.getDelay().setMath(SBMLutilities.myParseFormula("priority(" + lhpn.getTransition(t).getDelay() + "," + lhpn.getTransition(t).getPriority() + ")")); + } + else { + e.createDelay(); + e.getDelay().setMath(SBMLutilities.myParseFormula("priority(0," + lhpn.getTransition(t).getPriority() + ")")); + } + } + */ + + // Check if there is any self-loop. If the intersection between lhpn.getPreset(t) and lhpn.getPostset(t) + // is not empty, self-loop exists. + List t_postset = Arrays.asList(lhpn.getPostset(t)); + List t_intersect = new ArrayList(); // intersection of t_preset and t_postset + List t_NoIntersect = new ArrayList(); // t_NoIntersect = t_postset - t_preset + Boolean selfLoopFlag = false; + + // Check if there is intersection between the preset and postset. + for (String x : lhpn.getPreset(t)){ + if (t_postset.contains(x)){ + selfLoopFlag = true; + t_intersect.add(x); + } + } + if (selfLoopFlag) { + t_NoIntersect.removeAll(t_intersect); + // t_preset = 0 + for (String x : lhpn.getPreset(t)){ + EventAssignment assign0 = e.createEventAssignment(); + assign0.setVariable(x); + assign0.setMath(SBMLutilities.myParseFormula("0")); + // System.out.println("transition: " + t + " preset: " + x); + } + + // t_NoIntersect = 1 + for (String x : t_NoIntersect){ + EventAssignment assign1 = e.createEventAssignment(); + assign1.setVariable(x); + assign1.setMath(SBMLutilities.myParseFormula("1")); + // System.out.println("transition: " + t + " postset: " + x); + } + + } + else { // no self-loop + // t_preSet = 0 + for (String x : lhpn.getPreset(t)){ + EventAssignment assign0 = e.createEventAssignment(); + assign0.setVariable(x); + assign0.setMath(SBMLutilities.myParseFormula("0")); + // System.out.println("transition: " + t + " preset: " + x); + } + + // t_postSet = 1 + for (String x : lhpn.getPostset(t)){ + EventAssignment assign1 = e.createEventAssignment(); + assign1.setVariable(x); + assign1.setMath(SBMLutilities.myParseFormula("1")); + // System.out.println("transition: " + t + " postset: " + x); + } + } + + // assignment + // continuous assignment + if (lhpn.getContVars(t) != null){ + for (String var : lhpn.getContVars(t)){ + if (lhpn.getContAssign(t, var) != null) { + ExprTree assignContTree = lhpn.getContAssignTree(t, var); + String assignCont = assignContTree.toString("SBML"); + // System.out.println("continuous assign: "+ assignCont); + EventAssignment assign2 = e.createEventAssignment(); + assign2.setVariable(var); + assign2.setMath(SBMLutilities.myParseFormula(assignCont)); + } + } + } + + // integer assignment + if (lhpn.getIntVars()!= null){ + for (String var : lhpn.getIntVars()){ + if (lhpn.getIntAssign(t, var) != null) { + ExprTree assignIntTree = lhpn.getIntAssignTree(t, var); + String assignInt = assignIntTree.toString("SBML"); + // System.out.println("integer assignment from LHPN: " + var + " := " + assignInt); + EventAssignment assign3 = e.createEventAssignment(); + assign3.setVariable(var); + assign3.setMath(SBMLutilities.myParseFormula(assignInt)); + } + } + } + + // boolean assignment + if (selfLoopFlag) { + // if self-loop exists, create a new variable, extraVar, and a new event + String extraVar = t.concat("_extraVar"); + Parameter p = m.createParameter(); + p.setConstant(false); + p.setId(extraVar); + p.setValue(0); + + EventAssignment assign4ex = e.createEventAssignment(); + assign4ex.setVariable(extraVar); + assign4ex.setMath(SBMLutilities.myParseFormula("1")); + + // Create other boolean assignments + if (lhpn.getBooleanVars(t)!= null){ + for (String var :lhpn.getBooleanVars(t)){ + if (lhpn.getBoolAssign(t, var) != null) { + ExprTree assignBoolTree = lhpn.getBoolAssignTree(t, var); + String assignBool_tmp = assignBoolTree.toString("SBML"); + String assignBool = "piecewise(1," + assignBool_tmp + ",0)"; + //System.out.println("boolean assignment from LHPN: " + var + " := " + assignBool); + EventAssignment assign4 = e.createEventAssignment(); + assign4.setVariable(var); + assign4.setMath(SBMLutilities.myParseFormula(assignBool)); + } + } + } + + // create a new event + Event extraEvent = m.createEvent(); + extraEvent.setId("extra_" + t); + Trigger triggerExtra = extraEvent.createTrigger(); + //triggerExtra.setMath(SBMLutilities.myParseFormula("and(gt(t,0),eq(" + extraVar + ",1))")); + triggerExtra.setMath(SBMLutilities.myParseFormula("eq(" + extraVar + ",1)")); + //triggerExtra.setAnnotation(""); + triggerExtra.setPersistent(true); + triggerExtra.setInitialValue(false); + extraEvent.setUseValuesFromTriggerTime(false); + // assignments + EventAssignment assign5ex2 = extraEvent.createEventAssignment(); + for (String var : t_intersect){ + EventAssignment assign5ex1 = extraEvent.createEventAssignment(); + assign5ex1.setVariable(var); + assign5ex1.setMath(SBMLutilities.myParseFormula("1")); + } + assign5ex2.setVariable(extraVar); + assign5ex2.setMath(SBMLutilities.myParseFormula("0")); + } + else { + if (lhpn.getBooleanVars(t)!= null){ + for (String var :lhpn.getBooleanVars(t)){ + if (lhpn.getBoolAssign(t, var) != null) { + ExprTree assignBoolTree = lhpn.getBoolAssignTree(t, var); + String assignBool_tmp = assignBoolTree.toString("SBML"); + String assignBool = "piecewise(1," + assignBool_tmp + ",0)"; + //System.out.println("boolean assignment from LHPN: " + var + " := " + assignBool); + EventAssignment assign4 = e.createEventAssignment(); + assign4.setVariable(var); + assign4.setMath(SBMLutilities.myParseFormula(assignBool)); + } + } + } + } + + // rate assignment + if (lhpn.getRateVars(t)!= null){ + for (String var : lhpn.getRateVars(t)){ + // System.out.println("rate var: "+ var); + if (lhpn.getRateAssign(t, var) != null) { + ExprTree assignRateTree = lhpn.getRateAssignTree(t, var); + String assignRate = assignRateTree.toString("SBML"); + // System.out.println("rate assign: "+ assignRate); + + EventAssignment assign5 = e.createEventAssignment(); + assign5.setVariable(var + "_rate"); + assign5.setMath(SBMLutilities.myParseFormula(assignRate)); + } + } + } + // When translating a fail transition into an event, that event should assign to a special "fail" variable a value of 1. + // This "fail" variable should have initial value of 0. The SBML model should have a constraint "eq(fail,0)". + if (lhpn.getTransition(t).isFail()){ + Parameter failVar = m.createParameter(); + failVar.setConstant(false); + failVar.setId("failvar_" + t); + failVar.setValue(0); + EventAssignment assign6 = e.createEventAssignment(); + assign6.setVariable(failVar.getId()); + assign6.setMath(SBMLutilities.myParseFormula("1")); + Constraint failVarConstraint = m.createConstraint(); + SBMLutilities.setMetaId(failVarConstraint, "failtrans_" + t); + failVarConstraint.setMath(SBMLutilities.myParseFormula("eq(" + failVar.getId() + ", 0)")); + } + } + counter --; + } + + // Property parsing is dealt with in PropertyPanel.java + // translate the LPN property to SBML constraints + document = generateSBMLConstraints(document, property, lhpn); + } + + public void convertLPN2SBML(String lhpnFilename, String property) throws BioSimException { + this.filename = lhpnFilename.replace(".lpn", ".xml"); + // load lhpn file + LPN lhpn = new LPN(); + lhpn.load(lhpnFilename); + + // create sbml file + //document = new SBMLDocument(BioSim.SBML_LEVEL, BioSim.SBML_VERSION); + document = new SBMLDocument(3,1); + String[] filenameSplit = filename.split(GlobalConstants.separator); + String modelId = filenameSplit[filenameSplit.length-1].replace(".xml",""); + Model m = document.createModel(modelId); + + // Create bitwise operators for sbml + createFunction(m, "rate", "Rate", "lambda(a,a)"); + createFunction(m, "BIT", "bit selection", "lambda(a,b,a*b)"); + createFunction(m, "BITAND", "Bitwise AND", "lambda(a,b,a*b)"); + createFunction(m, "BITOR", "Bitwise OR", "lambda(a,b,a*b)"); + createFunction(m, "BITNOT", "Bitwise NOT", "lambda(a,b,a*b)"); + createFunction(m, "BITXOR", "Bitwise XOR", "lambda(a,b,a*b)"); + createFunction(m, "mod", "Modular", "lambda(a,b,a-floor(a/b)*b)"); + //createFunction(m, "and", "Logical AND", "lambda(a,b,a*b)"); + createFunction(m, "uniform", "Uniform distribution", "lambda(a,b,(a+b)/2)"); + createFunction(m, "normal", "Normal distribution", "lambda(m,s,m)"); + createFunction(m, "exponential", "Exponential distribution", "lambda(l,1/l)"); + createFunction(m, "gamma", "Gamma distribution", "lambda(a,b,a*b)"); + createFunction(m, "lognormal", "Lognormal distribution", "lambda(z,s,exp(z+s^2/2))"); + createFunction(m, "chisq", "Chi-squared distribution", "lambda(nu,nu)"); + createFunction(m, "laplace", "Laplace distribution", "lambda(a,0)"); + createFunction(m, "cauchy", "Cauchy distribution", "lambda(a,a)"); + createFunction(m, "rayleigh", "Rayleigh distribution", "lambda(s,s*sqrt(pi/2))"); + createFunction(m, "poisson", "Poisson distribution", "lambda(mu,mu)"); + createFunction(m, "binomial", "Binomial distribution", "lambda(p,n,p*n)"); + createFunction(m, "bernoulli", "Bernoulli distribution", "lambda(p,p)"); + + // translate from lhpn to sbml + // ----variables -> parameters----- + for (String v: lhpn.getVariables()){ + if (v != null){ + String initVal = lhpn.getInitialVal(v); + if (lhpn.isInteger(v)){ + Parameter var = m.createParameter(); + var.setConstant(false); + var.setId(v); + Pattern initVarIsIntPattern = Pattern.compile(Int); + Matcher initVarIsIntMatcher = initVarIsIntPattern.matcher(initVal); + boolean initVarIsInt = initVarIsIntMatcher.matches(); + Pattern initVarIsRangePattern = Pattern.compile(Range); + Matcher initVarIsRangeMatcher = initVarIsRangePattern.matcher(initVal); + boolean initVarIsRange = initVarIsRangeMatcher.matches(); + Pattern initRangeBoundPattern = Pattern.compile(Range); + Matcher initRangeBoundMatcher = initRangeBoundPattern.matcher(initVal); + boolean initVarRangeFound = initRangeBoundMatcher.find(); + if (initVarIsInt && !initVarIsRange) { + double initValDouble = Double.parseDouble(initVal); + var.setValue(initValDouble); + } + if (!initVarIsInt && initVarIsRange && initVarRangeFound) { + var.setValue(0); + if (!lhpn.isInput(v)) { + InitialAssignment initAssign = m.createInitialAssignment(); + initAssign.setVariable(var.getId()); + String initVarAssignRHS = "uniform("; + for (int i=1; i<=initRangeBoundMatcher.groupCount();i++) { + initVarAssignRHS = initVarAssignRHS + initRangeBoundMatcher.group(i); + if (i==1) + initVarAssignRHS = initVarAssignRHS + ","; + } + initVarAssignRHS = initVarAssignRHS + ")"; + initAssign.setMath(SBMLutilities.myParseFormula(initVarAssignRHS)); + } + } + if (lhpn.isInput(v)) { + SBMLutilities.createDirPort(document, v, GlobalConstants.INPUT); + } else if (lhpn.isOutput(v)) { + SBMLutilities.createDirPort(document, v, GlobalConstants.OUTPUT); + } + } else if (lhpn.isBoolean(v)) { // boolean variable + Parameter p = m.createParameter(); + p.setConstant(false); + p.setId(v); + p.setSBOTerm(GlobalConstants.SBO_LOGICAL); + String initValue = lhpn.getInitialVal(v); + // check initValue type; if boolean, set parameter value as 0 or 1. + if (initValue.equals("true")){ + p.setValue(1); + } + else { + p.setValue(0); + } + if (lhpn.isInput(v)) { + SBMLutilities.createDirPort(document, v, GlobalConstants.INPUT); + } else if (lhpn.isOutput(v)) { + SBMLutilities.createDirPort(document, v, GlobalConstants.OUTPUT); + } + } + } + } + + for (String v: lhpn.getContinuous().keySet()){ + String initVal = lhpn.getInitialVal(v); + Parameter var = m.createParameter(); + var.setConstant(false); + var.setId(v); + Pattern initVarIsIntPattern = Pattern.compile(Int); + Matcher initVarIsIntMatcher = initVarIsIntPattern.matcher(initVal); + boolean initVarIsInt = initVarIsIntMatcher.matches(); + Pattern initVarIsRangePattern = Pattern.compile(Range); + Matcher initVarIsRangeMatcher = initVarIsRangePattern.matcher(initVal); + boolean initVarIsRange = initVarIsRangeMatcher.matches(); + Pattern initRangeBoundPattern = Pattern.compile(Range); + Matcher initRangeBoundMatcher = initRangeBoundPattern.matcher(initVal); + boolean initVarRangeFound = initRangeBoundMatcher.find(); + if (initVarIsInt && !initVarIsRange) { + double initValDouble = Double.parseDouble(initVal); + var.setValue(initValDouble); + } + if (!initVarIsInt && initVarIsRange && initVarRangeFound) { + var.setValue(0); + if (!lhpn.isInput(v)) { + InitialAssignment initAssign = m.createInitialAssignment(); + initAssign.setVariable(var.getId()); + String initVarAssignRHS = "uniform("; + for (int i=1; i<=initRangeBoundMatcher.groupCount();i++) { + initVarAssignRHS = initVarAssignRHS + initRangeBoundMatcher.group(i); + if (i==1) + initVarAssignRHS = initVarAssignRHS + ","; + } + initVarAssignRHS = initVarAssignRHS + ")"; + initAssign.setMath(SBMLutilities.myParseFormula(initVarAssignRHS)); + } + } + if (!lhpn.isInput(v)) { + Parameter rateVar = m.createParameter(); + rateVar.setConstant(false); + rateVar.setId(v + "_" + GlobalConstants.RATE); + RateRule rateRule = m.createRateRule(); + SBMLutilities.setMetaId(rateRule, GlobalConstants.RULE+"_"+v+"_"+GlobalConstants.RATE); + rateRule.setVariable(v); + rateRule.setMath(SBMLutilities.myParseFormula(rateVar.getId())); + String initRate= lhpn.getInitialRate(v); + boolean initRateIsInt = Pattern.matches(Int, initRate); + boolean initRateIsRange = Pattern.matches(Range, initRate); + Pattern initRateRangePattern = Pattern.compile(Range); + Matcher initRateRangeMatcher = initRateRangePattern.matcher(initRate); + boolean initRateRangeFound = initRateRangeMatcher.find(); + if (initRateIsInt && !initRateIsRange) { + double initRateDouble = Double.parseDouble(initRate); + rateVar.setValue(initRateDouble); + } + if (!initRateIsInt && initRateIsRange && initRateRangeFound) { + rateVar.setValue(0); + InitialAssignment initAssign = m.createInitialAssignment(); + initAssign.setVariable(rateVar.getId()); + initAssign.setMath(SBMLutilities.myParseFormula(initRate)); + String initRateAssignRHS = "uniform("; + for (int i=1; i<=initRateRangeMatcher.groupCount();i++) { + initRateAssignRHS = initRateAssignRHS + initRateRangeMatcher.group(i); + if (i==1) + initRateAssignRHS = initRateAssignRHS + ","; + } + initRateAssignRHS = initRateAssignRHS + ")"; + initAssign.setMath(SBMLutilities.myParseFormula(initRateAssignRHS)); + } + } + if (lhpn.isInput(v)) { + SBMLutilities.createDirPort(document, v, GlobalConstants.INPUT); + } else if (lhpn.isOutput(v)) { + SBMLutilities.createDirPort(document, v, GlobalConstants.OUTPUT); + } + } + + // ----places -> species----- + for (String p: lhpn.getPlaceList()){ + Boolean initMarking = lhpn.getPlace(p).isMarked(); +// System.out.println(p + "=" + initMarking); + Parameter v = m.createParameter(); + v.setId(p); + v.setSBOTerm(GlobalConstants.SBO_PETRI_NET_PLACE); + v.setConstant(false); + if (initMarking){ + v.setValue(1); + } else { + v.setValue(0); + } + } + + // ----convert transitions ----- + for (String t : lhpn.getTransitionList()) { + Event e = m.createEvent(); + e.setId(t); + e.setSBOTerm(GlobalConstants.SBO_PETRI_NET_TRANSITION); + Trigger trigger = e.createTrigger(); + String EnablingTestNull = lhpn.getTransition(t).getEnabling(); + String Enabling; + if (EnablingTestNull == null){ + Enabling = "true"; // Enabling is true (Boolean) + } else { + Enabling = lhpn.getEnablingTree(t).toString("SBML"); + } + + //test Preset(t) + String CheckPreset = null; + int indexPreset = 0; + + // Check if all the presets of transition t are marked + // Transition t can fire only when all its preset are marked. + for (String x:lhpn.getPreset(t)){ + if (indexPreset == 0){ + CheckPreset = "eq(" + x + ",1)"; + } + else { + CheckPreset = "and(" + CheckPreset + "," + "eq(" + x + ",1)" + ")"; + } + indexPreset ++; + } + + // Is transition persistent? + if (!lhpn.getTransition(t).isPersistent() /*|| (lhpn.getTransition(t).isPersistent() && !lhpn.getTransition(t).hasConflict())*/){ + if (!lhpn.getTransition(t).isPersistent()) { + trigger.setPersistent(false); + } + else { + trigger.setPersistent(true); + } + if (CheckPreset==null) { + trigger.setMath(SBMLutilities.myParseFormula(Enabling)); + } else { + trigger.setMath(SBMLutilities.myParseFormula("and(" + Enabling + "," + CheckPreset + ")")); + } + } + else { // transition is persistent + // Create a rule for the persistent transition t. + AssignmentRule rulePersisTrigg = m.createAssignmentRule(); + SBMLutilities.setMetaId(rulePersisTrigg, GlobalConstants.TRIGGER+"_"+GlobalConstants.RULE+"_"+t); + String rulePersisTriggName = GlobalConstants.TRIGGER + "_" + t; + // Create a parameter (id = rulePersisTriggName). + Parameter rulePersisParam = m.createParameter(); + rulePersisParam.setId(rulePersisTriggName); + rulePersisParam.setValue(0); + rulePersisParam.setConstant(false); + rulePersisParam.setUnits(""); + String ruleExpBool = "or(and(" + Enabling + "," + CheckPreset + "), and(" + "eq(" + rulePersisTriggName + ", 1)," + CheckPreset + "))"; + String ruleExpReal = "piecewise(1, " + ruleExpBool + ", 0)"; + rulePersisTrigg.setVariable(rulePersisTriggName); + rulePersisTrigg.setMath(SBMLutilities.myParseFormula(ruleExpReal)); + trigger.setPersistent(false); + trigger.setMath(SBMLutilities.myParseFormula("eq(" + rulePersisTriggName + ", 1)")); + } + + // TriggerInitiallyFalse + // trigger.setAnnotation(""); + trigger.setInitialValue(false); + + // use values at trigger time = false + e.setUseValuesFromTriggerTime(false); + + // Priority and delay + if (lhpn.getTransition(t).getDelay()!=null) { + e.createDelay(); + String delay = lhpn.getTransition(t).getDelayTree().toString("SBML"); + e.getDelay().setMath(SBMLutilities.myParseFormula(delay)); + } + if (lhpn.getTransition(t).getPriority()!=null) { + e.createPriority(); + String priority = lhpn.getTransition(t).getPriorityTree().toString("SBML"); + e.getPriority().setMath(SBMLutilities.myParseFormula(priority)); + } + + // Check if there is any self-loop. If the intersection between lhpn.getPreset(t) and lhpn.getPostset(t) + // is not empty, self-loop exists. + List t_postset = Arrays.asList(lhpn.getPostset(t)); + List t_intersect = new ArrayList(); // intersection of t_preset and t_postset + List t_NoIntersect = new ArrayList(); // t_NoIntersect = t_postset - t_preset + Boolean selfLoopFlag = false; + + // Check if there is intersection between the preset and postset. + for (String x : lhpn.getPreset(t)){ + if (t_postset.contains(x)){ + selfLoopFlag = true; + t_intersect.add(x); + } + } + if (selfLoopFlag) { + t_NoIntersect.removeAll(t_intersect); + // t_preset = 0 + for (String x : lhpn.getPreset(t)){ + EventAssignment assign0 = e.createEventAssignment(); + assign0.setVariable(x); + assign0.setMath(SBMLutilities.myParseFormula("0")); + // System.out.println("transition: " + t + " preset: " + x); + } + + // t_NoIntersect = 1 + for (String x : t_NoIntersect){ + EventAssignment assign1 = e.createEventAssignment(); + assign1.setVariable(x); + assign1.setMath(SBMLutilities.myParseFormula("1")); + // System.out.println("transition: " + t + " postset: " + x); + } + + } + else { // no self-loop + // t_preSet = 0 + for (String x : lhpn.getPreset(t)){ + EventAssignment assign0 = e.createEventAssignment(); + assign0.setVariable(x); + assign0.setMath(SBMLutilities.myParseFormula("0")); + // System.out.println("transition: " + t + " preset: " + x); + } + + // t_postSet = 1 + for (String x : lhpn.getPostset(t)){ + EventAssignment assign1 = e.createEventAssignment(); + assign1.setVariable(x); + assign1.setMath(SBMLutilities.myParseFormula("1")); + // System.out.println("transition: " + t + " postset: " + x); + } + } + + // assignment + // continuous assignment + if (lhpn.getContVars(t) != null){ + for (String var : lhpn.getContVars(t)){ + if (lhpn.getContAssign(t, var) != null) { + ExprTree assignContTree = lhpn.getContAssignTree(t, var); + String assignCont = assignContTree.toString("SBML"); + // System.out.println("continuous assign: "+ assignCont); + EventAssignment assign2 = e.createEventAssignment(); + assign2.setVariable(var); + assign2.setMath(SBMLutilities.myParseFormula(assignCont)); + } + } + } + + // integer assignment + if (lhpn.getIntVars()!= null){ + for (String var : lhpn.getIntVars()){ + if (lhpn.getIntAssign(t, var) != null) { + ExprTree assignIntTree = lhpn.getIntAssignTree(t, var); + String assignInt = assignIntTree.toString("SBML"); + // System.out.println("integer assignment from LHPN: " + var + " := " + assignInt); + EventAssignment assign3 = e.createEventAssignment(); + assign3.setVariable(var); + assign3.setMath(SBMLutilities.myParseFormula(assignInt)); + } + } + } + + // boolean assignment + if (selfLoopFlag) { + // if self-loop exists, create a new variable, extraVar, and a new event + String extraVar = t.concat("_extraVar"); + Parameter p = m.createParameter(); + p.setConstant(false); + p.setId(extraVar); + p.setValue(0); + p.setSBOTerm(GlobalConstants.SBO_PETRI_NET_PLACE); + + EventAssignment assign4ex = e.createEventAssignment(); + assign4ex.setVariable(extraVar); + assign4ex.setMath(SBMLutilities.myParseFormula("1")); + + // Create other boolean assignments + if (lhpn.getBooleanVars(t)!= null){ + for (String var :lhpn.getBooleanVars(t)){ + if (lhpn.getBoolAssign(t, var) != null) { + ExprTree assignBoolTree = lhpn.getBoolAssignTree(t, var); + String assignBool_tmp = assignBoolTree.toString("SBML"); + String assignBool = "piecewise(1," + assignBool_tmp + ",0)"; + //System.out.println("boolean assignment from LHPN: " + var + " := " + assignBool); + EventAssignment assign4 = e.createEventAssignment(); + assign4.setVariable(var); + assign4.setMath(SBMLutilities.myParseFormula(assignBool)); + } + } + } + + // create a new event + Event extraEvent = m.createEvent(); + extraEvent.setId("extra_" + t); + extraEvent.setSBOTerm(GlobalConstants.SBO_PETRI_NET_TRANSITION); + Trigger triggerExtra = extraEvent.createTrigger(); + //triggerExtra.setMath(SBMLutilities.myParseFormula("and(gt(t,0),eq(" + extraVar + ",1))")); + triggerExtra.setMath(SBMLutilities.myParseFormula("and(true,eq(" + extraVar + ",1))")); + //triggerExtra.setAnnotation(""); + triggerExtra.setPersistent(false); + triggerExtra.setInitialValue(false); + extraEvent.setUseValuesFromTriggerTime(false); + // assignments + EventAssignment assign5ex2 = extraEvent.createEventAssignment(); + for (String var : t_intersect){ + EventAssignment assign5ex1 = extraEvent.createEventAssignment(); + assign5ex1.setVariable(var); + assign5ex1.setMath(SBMLutilities.myParseFormula("1")); + } + assign5ex2.setVariable(extraVar); + assign5ex2.setMath(SBMLutilities.myParseFormula("0")); + } + else { + if (lhpn.getBooleanVars(t)!= null){ + for (String var :lhpn.getBooleanVars(t)){ + if (lhpn.getBoolAssign(t, var) != null) { + ExprTree assignBoolTree = lhpn.getBoolAssignTree(t, var); + String assignBool_tmp = assignBoolTree.toString("SBML"); + String assignBool = "piecewise(1," + assignBool_tmp + ",0)"; + //System.out.println("boolean assignment from LHPN: " + var + " := " + assignBool); + EventAssignment assign4 = e.createEventAssignment(); + assign4.setVariable(var); + assign4.setMath(SBMLutilities.myParseFormula(assignBool)); + } + } + } + } + + // rate assignment + if (lhpn.getRateVars(t)!= null){ + for (String var : lhpn.getRateVars(t)){ + // System.out.println("rate var: "+ var); + if (lhpn.getRateAssign(t, var) != null) { + ExprTree assignRateTree = lhpn.getRateAssignTree(t, var); + String assignRate = assignRateTree.toString("SBML"); + // System.out.println("rate assign: "+ assignRate); + + EventAssignment assign5 = e.createEventAssignment(); + assign5.setVariable(var + "_" + GlobalConstants.RATE); + assign5.setMath(SBMLutilities.myParseFormula(assignRate)); + } + } + } + // When translating a fail transition into an event, that event should assign to a special "fail" variable a value of 1. + // This "fail" variable should have initial value of 0. The SBML model should have a constraint "eq(fail,0)". + if (lhpn.getTransition(t).isFail()){ + Parameter failVar = m.getParameter(GlobalConstants.FAIL); + if (failVar==null) { + failVar = m.createParameter(); + failVar.setConstant(false); + failVar.setId(GlobalConstants.FAIL); + failVar.setValue(0); + failVar.setSBOTerm(GlobalConstants.SBO_LOGICAL); + Constraint failVarConstraint = m.createConstraint(); + SBMLutilities.setMetaId(failVarConstraint, GlobalConstants.FAIL_TRANSITION); + failVarConstraint.setMath(SBMLutilities.myParseFormula("eq(" + failVar.getId() + ", 0)")); + } + EventAssignment assign6 = e.createEventAssignment(); + assign6.setVariable(failVar.getId()); + assign6.setMath(SBMLutilities.myParseFormula("1")); + } + } + // Property parsing is dealt with in PropertyPanel.java + // translate the LPN property to SBML constraints + document = generateSBMLConstraints(document, property, lhpn); + } + + private void createFunction(Model model, String id, String name, String formula) { + if (document.getModel().getFunctionDefinition(id) == null) { + FunctionDefinition f = model.createFunctionDefinition(); + f.setId(id); + f.setName(name); + try { + IFormulaParser parser = new FormulaParserLL3(new StringReader("")); + f.setMath(ASTNode.parseFormula(formula, parser)); + } + catch (ParseException e) { + e.printStackTrace(); + } + catch (Exception e) { + e.printStackTrace(); + } + } +} + + public void outputSBML() { + SBMLutilities.pruneUnusedSpecialFunctions(document); + SBMLWriter writer = new SBMLWriter(); + try { + writer.writeSBMLToFile(document, filename); + } + catch (SBMLException e) { + e.printStackTrace(); + } + catch (FileNotFoundException e) { + e.printStackTrace(); + } + catch (XMLStreamException e) { + e.printStackTrace(); + } + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public String getFilename() { + return filename; + } + + public static SBMLDocument generateSBMLConstraints(SBMLDocument doc, String property, LPN lhpn) throws BioSimException { + String probprop = ""; + String[] probpropParts = new String[4]; + if(!(property == null) && !property.equals("") && !property.equals("none")){ + Model m = doc.getModel(); + probprop=getProbpropExpression(property); + if (!isSteadyState && !isHSF) { + probpropParts=getProbpropParts(probprop); + // Convert extracted property parts into SBML constraints + // probpropParts=[probpropLeft, probpropRight, lowerBound, upperBound] + Constraint constraintFail = m.createConstraint(); + Constraint constraintSucc = m.createConstraint(); + SBMLutilities.setMetaId(constraintFail, "Fail"); + SBMLutilities.setMetaId(constraintSucc, "Success"); + ExprTree probpropLeftTree = null; + ExprTree probpropRightTree = null; + ExprTree lowerBoundTree = null; + ExprTree upperBoundTree = null; + String probpropLeftSBML = null; + String probpropRightSBML = null; + String lowerBoundSBML = null; + String upperBoundSBML = null; + + if (!probpropParts[0].equals("")) + probpropLeftTree = String2ExprTree(lhpn,probpropParts[0]); + if (!probpropParts[1].equals("")) + probpropRightTree = String2ExprTree(lhpn,probpropParts[1]); + if (!probpropParts[2].equals("")) + lowerBoundTree = String2ExprTree(lhpn,probpropParts[2]); + if (!probpropParts[3].equals("")) + upperBoundTree = String2ExprTree(lhpn,probpropParts[3]); + if (!(probpropLeftTree == null)) + probpropLeftSBML = probpropLeftTree.toString("SBML"); + if (!(probpropRightTree == null)) + probpropRightSBML = probpropRightTree.toString("SBML"); + if (!(lowerBoundTree == null)) + lowerBoundSBML = lowerBoundTree.toString("SBML"); + if (!(upperBoundTree == null)) + upperBoundSBML = upperBoundTree.toString("SBML"); + + String LTlower = "lt(t," + lowerBoundSBML + ")"; + String LEQlower = "leq(t," + lowerBoundSBML + ")"; + String GTlower = "gt(t," + lowerBoundSBML + ")"; + String GEQlower = "geq(t," + lowerBoundSBML + ")"; + String EQlower = "eq(t," + lowerBoundSBML + ")"; + String LEQupper = "leq(t," + upperBoundSBML + ")"; + String LTupper = "lt(t," + upperBoundSBML + ")"; + String GTupper = "gt(t," + upperBoundSBML + ")"; + String GEQupper = "geq(t," + upperBoundSBML + ")"; + + int relopType = Integer.parseInt(probpropParts[4]); + // construct the SBML constraints + if (property.contains("PU")){ // A PU B (Time bounds are specified below.) + switch (relopType) { + case 0:{ // [l,u] + // Fail: (A || (B && (t>=l))) && (t<=u) + // Success: !B || (tu) + constraintFail.setMath(SBMLutilities.myParseFormula("and(" + "or("+probpropLeftSBML + "," + "and(" + probpropRightSBML + "," + GEQlower + ")" + ")" + "," + LEQupper + ")")); + constraintSucc.setMath(SBMLutilities.myParseFormula("or(" + "or(" + "not(" + probpropRightSBML + ")" + "," + LTlower + ")" + "," + GTupper + ")")); + break; + } + case 1: { // [<=u] + // Fail: (A || B) && (t<=u) + // Success: (!B) || (t>u) + constraintFail.setMath(SBMLutilities.myParseFormula("and(" + "or(" + probpropLeftSBML + "," + probpropRightSBML + ")" + "," + LEQupper + ")")); + constraintSucc.setMath(SBMLutilities.myParseFormula("or(" + "not(" + probpropRightSBML + ")" + "," + GTupper + ")")); + break; + } + case 2: { // [=u) + constraintFail.setMath(SBMLutilities.myParseFormula("and(" + "or(" + probpropLeftSBML + "," + probpropRightSBML + ")" + "," + LTupper + ")")); + constraintSucc.setMath(SBMLutilities.myParseFormula("or(" + "not(" + probpropRightSBML + ")" + "," + GEQupper + ")")); + break; + } + case 3: { // [>=l] + // Fail: A || (B && (t>=l)) + // Success: (!B) || (tl] + // Fail: A || (B && (t>l)) + // Success: !B || (t<=l) + constraintFail.setMath(SBMLutilities.myParseFormula("or(" + probpropLeftSBML + "," + "and(" + probpropRightSBML + "," + GTlower + ")" + ")")); + constraintSucc.setMath(SBMLutilities.myParseFormula("or(" + "not(" + probpropRightSBML + ")" + "," + LEQlower + ")")); + break; + } + case 5: { // [=k] (k was stored as lowerBound) + // Fail: (A && (t<=k)) || (B && (t=k)) + // Success: !B || (t>k) || (tu) + constraintFail.setMath(SBMLutilities.myParseFormula(LEQupper)); + constraintSucc.setMath(SBMLutilities.myParseFormula("or(" + "or(" + "not(" + probpropRightSBML + ")" + "," + LTlower + ")" + "," + GTupper + ")")); + break; + } + case 1: { // [<=u] + // Fail: t<=u + // Success: !A || (t>u) + constraintFail.setMath(SBMLutilities.myParseFormula(LEQupper)); + constraintSucc.setMath(SBMLutilities.myParseFormula("or(" + "not(" + probpropRightSBML + ")" + "," + GTupper + ")")); + break; + } + case 2: { // [=u) + constraintFail.setMath(SBMLutilities.myParseFormula(LTupper)); + constraintSucc.setMath(SBMLutilities.myParseFormula("or(" + "not(" + probpropRightSBML + ")" + "," + GEQupper + ")")); + break; + } + case 3: { // [>=l] + // Fail: --- + // Success: !A || (tl] + // Fail: --- + // Success: !A || (t<=l) + m.removeConstraint(0); + constraintSucc.setMath(SBMLutilities.myParseFormula("or(" + "not(" + probpropRightSBML + ")" + "," + LEQlower + ")")); + break; + } + case 5: { // [=k] + // Fail: t<=k + // Success: !A || (tk) + constraintFail.setMath(SBMLutilities.myParseFormula(EQlower)); + constraintSucc.setMath(SBMLutilities.myParseFormula("or(" + "or(" + "not(" + probpropRightSBML + ")" + "," + LTlower + ")" + "," + GTlower + ")")); + break; + } + } + } + if (property.contains("PG")){ + switch (relopType) { + case 0:{ // [l,u] + // Fail: A || (tu) + // Success: t<=u + constraintFail.setMath(SBMLutilities.myParseFormula("or(" + "or(" + probpropRightSBML + "," + LTlower + ")" + "," + GTupper + ")")); + constraintSucc.setMath(SBMLutilities.myParseFormula(LEQupper)); + break; + } + case 1: { // [<=u] + // Fail: A || (t>u) + // Success: t<=u + constraintFail.setMath(SBMLutilities.myParseFormula("or(" + probpropRightSBML + "," + GTupper + ")")); + constraintSucc.setMath(SBMLutilities.myParseFormula(LEQupper)); + break; + } + case 2: { // [=u) + // Success: t=l] + // Fail: A || (tl] + // Fail: A || (t<=l) + // Success: --- + constraintFail.setMath(SBMLutilities.myParseFormula("or(" + probpropRightSBML + "," + LEQlower + ")")); + m.removeConstraint(1); + break; + } + case 5: { // [=k] + // Fail: A || (t>k) || (t=0.99{(true)PU[3,10]((A<8)&&(R>4))]} + public static String getProbpropExpression(String property) throws BioSimException{ + //System.out.println("property (getProbpropExpression)= " + property); + String probprop=""; + // probproperty + if (property.startsWith("Pr") || property.startsWith("St")){ + if(property.startsWith("St")) + isSteadyState = true; + // remove Pr/St from the property spec + property=property.substring(2); + boolean relopFlag = property.startsWith(">") + || property.startsWith(">=") + || property.startsWith("<") + || property.startsWith("<=") + || (property.startsWith("=") && !property.contains("?")); + if (relopFlag){ + if(property.startsWith(">=") || property.startsWith("<=")){ + property=property.substring(2); + } + else{ + property=property.substring(1); + } + // check the probability value after relop + String probabilityVal = property.substring(0,property.indexOf("{")); + Pattern ProbabilityValuePattern = Pattern.compile(probabilityValue); + Matcher ProbabilityValueMatcher = ProbabilityValuePattern.matcher(probabilityVal); + boolean correctProbabilityValue = ProbabilityValueMatcher.matches(); + if(correctProbabilityValue) { + property=property.replaceFirst(probabilityVal, ""); + property=property.replace("{", ""); + property=property.replace("}", ""); + probprop=property; + } + else{ + throw new BioSimException("Invalid probability value", "Error in Property"); + } + } + else if(property.startsWith("{")) { // shorthand version: Pr{Psi} and St{Psi} + property=property.substring(1); + property=property.substring(0,property.lastIndexOf('}')) + property.substring(property.lastIndexOf('}')+1); + probprop=property; + } + else if(property.startsWith("=") && property.contains("?")){ // full version: Pr=?{Psi} and St=?{Psi} + property=property.substring(3); + property=property.substring(0,property.lastIndexOf('}')) + property.substring(property.lastIndexOf('}')+1); + probprop=property; + } + } + else { // hsf + isHSF = true; + } + return probprop; + } + + public static String convertProperty(ASTNode prop) { + String property = "Pr=?{"; + String operator = ""; + if (prop.getType()==ASTNode.Type.FUNCTION) { + if (prop.getName().equals("G")) { + operator += "PG"; + } + else if (prop.getName().equals("F")) { + operator += "PF"; + } + else if (prop.getName().equals("U")) { + operator += "PU"; + } + else if (prop.getName().equals("St")) { + property = "St=?{" + convertHelper(prop.getChild(0)) + "}"; + return property; + } + } + ASTNode node = prop.getChild(0); + if (node.getType() == ASTNode.Type.LOGICAL_AND) { + String min = "0"; + String max = "inf"; + ASTNode child; + for (int i = 0; i < node.getChildCount(); i++) { + child = node.getChild(i); + if (child.getType() == ASTNode.Type.RELATIONAL_LT) { + if (child.getChild(0).isNumber()) { + max = SBMLutilities.myFormulaToString(child.getChild(0)); + } + else if (child.getChild(1).isNumber()) { + min = SBMLutilities.myFormulaToString(child.getChild(1)); + } + } + else if (child.getType() == ASTNode.Type.RELATIONAL_LEQ) { + if (child.getChild(0).isNumber()) { + max = SBMLutilities.myFormulaToString(child.getChild(0)); + } + else if (child.getChild(1).isNumber()) { + min = SBMLutilities.myFormulaToString(child.getChild(1)); + } + } + else if (child.getType() == ASTNode.Type.RELATIONAL_GT) { + if (child.getChild(0).isNumber()) { + min = SBMLutilities.myFormulaToString(child.getChild(0)); + } + else if (child.getChild(1).isNumber()) { + max = SBMLutilities.myFormulaToString(child.getChild(1)); + } + } + else if (child.getType() == ASTNode.Type.RELATIONAL_GEQ) { + if (child.getChild(0).isNumber()) { + min = SBMLutilities.myFormulaToString(child.getChild(0)); + } + else if (child.getChild(1).isNumber()) { + max = SBMLutilities.myFormulaToString(child.getChild(1)); + } + } + } + operator += "[" + min + "," + max + "]"; + } + else if (node.getType() == ASTNode.Type.RELATIONAL_LT) { + if (node.getChild(0).isNumber()) { + operator += "[>" + SBMLutilities.myFormulaToString(node.getChild(0)) + "]"; + } + else if (node.getChild(1).isNumber()) { + operator += "[<" + SBMLutilities.myFormulaToString(node.getChild(1)) + "]"; + } + } + else if (node.getType() == ASTNode.Type.RELATIONAL_LEQ) { + if (node.getChild(0).isNumber()) { + operator += "[>=" + SBMLutilities.myFormulaToString(node.getChild(0)) + "]"; + } + else if (node.getChild(1).isNumber()) { + operator += "[<=" + SBMLutilities.myFormulaToString(node.getChild(1)) + "]"; + } + } + else if (node.getType() == ASTNode.Type.RELATIONAL_GT) { + if (node.getChild(0).isNumber()) { + operator += "[<" + SBMLutilities.myFormulaToString(node.getChild(0)) + "]"; + } + else if (node.getChild(1).isNumber()) { + operator += "[>" + SBMLutilities.myFormulaToString(node.getChild(1)) + "]"; + } + } + else if (node.getType() == ASTNode.Type.RELATIONAL_GEQ) { + if (node.getChild(0).isNumber()) { + operator += "[<=" + SBMLutilities.myFormulaToString(node.getChild(0)) + "]"; + } + else if (node.getChild(1).isNumber()) { + operator += "[>=" + SBMLutilities.myFormulaToString(node.getChild(1)) + "]"; + } + } + else if (node.getType() == ASTNode.Type.RELATIONAL_EQ) { + if (node.getChild(0).isNumber()) { + operator += "[=" + SBMLutilities.myFormulaToString(node.getChild(0)) + "]"; + } + else if (node.getChild(1).isNumber()) { + operator += "[=" + SBMLutilities.myFormulaToString(node.getChild(1)) + "]"; + } + } + else { + operator += "[0,inf]"; + } + if (prop.getType()==ASTNode.Type.FUNCTION) { + if (prop.getName().equals("G") || prop.getName().equals("F")) { + property += operator + convertHelper(prop.getChild(1)); + } + else if (prop.getName().equals("U")) { + property += convertHelper(prop.getChild(1)) + operator + convertHelper(prop.getChild(2)); + } + } + property += "}"; + return property; + } + + private static String convertHelper(ASTNode op) { + String convert = ""; + if (op.getType()==ASTNode.Type.LOGICAL_AND) { + convert = "(" + convertHelper(op.getChild(0)); + for (int i = 1; i < op.getChildCount(); i++) { + convert += "&" + convertHelper(op.getChild(i)); + } + convert += ")"; + return convert; + } + else if (op.getType()==ASTNode.Type.LOGICAL_OR) { + convert = "(" + convertHelper(op.getChild(0)); + for (int i = 1; i < op.getChildCount(); i++) { + convert += "|" + convertHelper(op.getChild(i)); + } + convert += ")"; + return convert; + } + else if (op.getType()==ASTNode.Type.LOGICAL_NOT) { + convert = "~(" + convertHelper(op.getChild(0)) + ")"; + return convert; + } + else if (op.getType()==ASTNode.Type.RELATIONAL_LT) { + convert = "(" + convertHelper(op.getChild(0)) + "<" + convertHelper(op.getChild(1)) + ")"; + return convert; + } + else if (op.getType()==ASTNode.Type.RELATIONAL_LEQ) { + convert = "(" + convertHelper(op.getChild(0)) + "<=" + convertHelper(op.getChild(1)) + ")"; + return convert; + } + else if (op.getType()==ASTNode.Type.RELATIONAL_GT) { + convert = "(" + convertHelper(op.getChild(0)) + ">" + convertHelper(op.getChild(1)) + ")"; + return convert; + } + else if (op.getType()==ASTNode.Type.RELATIONAL_GEQ) { + convert = "(" + convertHelper(op.getChild(0)) + ">=" + convertHelper(op.getChild(1)) + ")"; + return convert; + } + else if (op.getType()==ASTNode.Type.RELATIONAL_GEQ) { + convert = "(" + convertHelper(op.getChild(0)) + "=" + convertHelper(op.getChild(1)) + ")"; + return convert; + } + else if (op.isSetName() && op.getName().equals("PSt")) { + return "St=?{" + convertHelper(op.getChild(0)) + "}"; + } + else if (op.isSetName() && + (op.getName().equals("PG") || op.getName().equals("PF") || op.getName().equals("PU"))) { + String operator = ""; + if (op.isSetName() && op.getName().equals("PG")) { + operator += "G"; + } + else if (op.isSetName() && op.getName().equals("PF")) { + operator += "F"; + } + else { + operator += "U"; + } + ASTNode node = op.getChild(0); + if (node.getType()==ASTNode.Type.LOGICAL_AND) { + String min = "0"; + String max = "inf"; + ASTNode child; + for (int i = 0; i < node.getChildCount(); i++) { + child = node.getChild(i); + if (child.getType()==ASTNode.Type.RELATIONAL_LT) { + if (child.getChild(0).isNumber()) { + max = SBMLutilities.myFormulaToString(child.getChild(0)); + } + else if (child.getChild(1).isNumber()) { + min = SBMLutilities.myFormulaToString(child.getChild(1)); + } + } + else if (child.getType()==ASTNode.Type.RELATIONAL_LEQ) { + if (child.getChild(0).isNumber()) { + max = SBMLutilities.myFormulaToString(child.getChild(0)); + } + else if (child.getChild(1).isNumber()) { + min = SBMLutilities.myFormulaToString(child.getChild(1)); + } + } + else if (child.getType()==ASTNode.Type.RELATIONAL_GT) { + if (child.getChild(0).isNumber()) { + min = SBMLutilities.myFormulaToString(child.getChild(0)); + } + else if (child.getChild(1).isNumber()) { + max = SBMLutilities.myFormulaToString(child.getChild(1)); + } + } + else if (child.getType()==ASTNode.Type.RELATIONAL_GEQ) { + if (child.getChild(0).isNumber()) { + min = SBMLutilities.myFormulaToString(child.getChild(0)); + } + else if (child.getChild(1).isNumber()) { + max = SBMLutilities.myFormulaToString(child.getChild(1)); + } + } + } + operator += "[" + min + "," + max + "]"; + } + else if (node.getType()==ASTNode.Type.RELATIONAL_LT) { + if (node.getChild(0).isNumber()) { + operator += "[>" + SBMLutilities.myFormulaToString(node.getChild(0)) + "]"; + } + else if (node.getChild(1).isNumber()) { + operator += "[<" + SBMLutilities.myFormulaToString(node.getChild(1)) + "]"; + } + } + else if (node.getType()==ASTNode.Type.RELATIONAL_LEQ) { + if (node.getChild(0).isNumber()) { + operator += "[>=" + SBMLutilities.myFormulaToString(node.getChild(0)) + "]"; + } + else if (node.getChild(1).isNumber()) { + operator += "[<=" + SBMLutilities.myFormulaToString(node.getChild(1)) + "]"; + } + } + else if (node.getType()==ASTNode.Type.RELATIONAL_GT) { + if (node.getChild(0).isNumber()) { + operator += "[<" + SBMLutilities.myFormulaToString(node.getChild(0)) + "]"; + } + else if (node.getChild(1).isNumber()) { + operator += "[>" + SBMLutilities.myFormulaToString(node.getChild(1)) + "]"; + } + } + else if (node.getType()==ASTNode.Type.RELATIONAL_GEQ) { + if (node.getChild(0).isNumber()) { + operator += "[<=" + SBMLutilities.myFormulaToString(node.getChild(0)) + "]"; + } + else if (node.getChild(1).isNumber()) { + operator += "[>=" + SBMLutilities.myFormulaToString(node.getChild(1)) + "]"; + } + } + else if (node.getType()==ASTNode.Type.RELATIONAL_EQ) { + if (node.getChild(0).isNumber()) { + operator += "[=" + SBMLutilities.myFormulaToString(node.getChild(0)) + "]"; + } + else if (node.getChild(1).isNumber()) { + operator += "[=" + SBMLutilities.myFormulaToString(node.getChild(1)) + "]"; + } + } + else { + operator += "[0,inf]"; + } + if (op.getName()!=null && (op.getName().equals("PG") || op.getName().equals("PF"))) { + return "Pr=?{" + operator + convertHelper(op.getChild(1)) + "}"; + } + return "Pr=?{" + convertHelper(op.getChild(1)) + operator + convertHelper(op.getChild(2)) + "}"; + } + else { + String finalString = SBMLutilities.myFormulaToString(op); + String[] opers = new String[] { "and(", "or(", "not(", "lt(", "leq(", "gt(", "geq(", "eq(", "PG(", "PF(", "PU(" }; + for (String o : opers) { + while (finalString.contains(o)) { + String temp = finalString.substring(finalString.indexOf(o) + o.length()); + String formula = "o"; + int paren = 1; + while (paren != 0) { + char c = temp.charAt(0); + if (c == '(') { + paren++; + } + else if (c == ')') { + paren--; + } + formula += c; + temp.substring(1); + } + finalString = finalString.substring(0, finalString.indexOf(o)) + + convertHelper(SBMLutilities.myParseFormula(formula)) + temp; + } + } + return finalString; + } + /* + String finalString = SBMLutilities.myFormulaToString(op); + String[] opers = new String[] { "and(", "or(", "not(", "lt(", "leq(", "gt(", "geq(", "eq(", "PG(", "PF(", "PU(" }; + for (String o : opers) { + while (finalString.contains(o)) { + String temp = finalString.substring(finalString.indexOf(o) + o.length()); + String formula = "o"; + int paren = 1; + while (paren != 0) { + char c = temp.charAt(0); + if (c == '(') { + paren++; + } + else if (c == ')') { + paren--; + } + formula += c; + temp.substring(1); + } + finalString = finalString.substring(0, finalString.indexOf(o)) + + convertHelper(SBMLutilities.myParseFormula(formula)) + temp; + } + } + return finalString; + */ + } + + // getProbpropParts extracts the expressions before and after the PU (after PG and PF) + // and the time bound from the probprop + // Currently, we assume no nested until property + public static String[] getProbpropParts(String probprop) throws BioSimException{ + String symbol = "@"; + String[] probpropParts; + probpropParts = new String[5]; + boolean PUFlag = probprop.contains("PU"); + boolean PFFlag = probprop.contains("PF"); + boolean PGFlag = probprop.contains("PG"); + String operator; + if (PUFlag) { + operator = "PU"; + } + else if (PFFlag) { + operator = "PF"; + } + else { + operator = "PG"; + } + String probpropRight=""; + String probpropLeft=""; + String timeBound=""; + String upperBound=""; + String lowerBound=""; + String relopType = ""; +// probprop.replaceAll("\\W", ""); + if (!probprop.contains(" ")) { + if (!probprop.equals("")){ + // property should be in this format at this stage: probprop + // obtain the hsf AFTER bound + probpropRight= probprop.substring(probprop.indexOf(operator)).substring(probprop.substring(probprop.indexOf(operator)).indexOf("]")+1, probprop.substring(probprop.indexOf(operator)).length()); + // obtain the time bound + timeBound= probprop.substring(probprop.indexOf(operator)).substring(probprop.substring(probprop.indexOf(operator)).indexOf("["), probprop.substring(probprop.indexOf(operator)).indexOf("]")+1); + // bound: [lower, upper] + if (timeBound.contains(",")){ + relopType = "0"; + lowerBound = timeBound.substring(timeBound.indexOf("[")+1, timeBound.indexOf(",")); + upperBound = timeBound.substring(timeBound.indexOf(",")+1, timeBound.indexOf("]")); + } + // bound: [<=upper] + else if(timeBound.contains("<=")){ + relopType = "1"; + lowerBound = "0"; + upperBound = timeBound.substring(timeBound.indexOf("<")+2, timeBound.indexOf("]")); + } + // bound: [=lower] + else if (timeBound.contains(">=")) { + relopType = "3"; + lowerBound = timeBound.substring(timeBound.indexOf(">")+2, timeBound.indexOf("]")); + upperBound = "inf"; + } + // bound: [>lower] + else if (timeBound.contains(">") && !timeBound.contains("=")){ + relopType = "4"; + lowerBound = timeBound.substring(timeBound.indexOf(">")+1, timeBound.indexOf("]")); + upperBound = "inf"; + } + // bound: [=k] (k is treated as lowerBound) + else if (timeBound.contains("=") && !timeBound.contains("<") && !timeBound.contains(">")) { + relopType = "5"; + lowerBound = timeBound.substring(timeBound.indexOf("=")+1, timeBound.indexOf("]")); + upperBound = lowerBound; + } + if(PUFlag){ + probprop = probprop.replace("PU",symbol); + // obtain the logic BEFORE the temporal operator + probpropLeft= probprop.substring(0, probprop.indexOf(symbol)); + // if probpropLeft has a pair of outermost parentheses, remove them + if (probpropLeft.startsWith("(") && probpropLeft.endsWith(")")){ + probpropLeft=probprop.substring(1,probpropLeft.length()-1); + } + if (probpropRight.startsWith("(") && probpropRight.endsWith(")")) { + probpropRight=probpropRight.substring(1,probpropRight.length()-1); + } + } + if(PFFlag){ + // Remove the outermost parentheses. At this point, probpropRight = (hsf) + if (probpropRight.startsWith("(")) { + probpropRight=probpropRight.substring(1,probpropRight.length()-1); + } + } + if(PGFlag){ + // Remove the outermost parentheses. At this point, probpropRight = (hsf) + if (probpropRight.startsWith("(")) { + probpropRight=probpropRight.substring(1,probpropRight.length()-1); + } + } + } + else { // isHSF = true + throw new BioSimException("Property does not contain the until operator", "Warning in Property"); + } + } + else { + throw new BioSimException("Property contains white space", "Error in Property"); + } + probpropParts[0]=probpropLeft; + probpropParts[1]=probpropRight; + probpropParts[2]=lowerBound; + probpropParts[3]=upperBound; + probpropParts[4]=relopType; + return probpropParts; + } + + public static ExprTree String2ExprTree(LPN lhpn, String str) { + ExprTree result = new ExprTree(lhpn); + ExprTree expr = new ExprTree(lhpn); + expr.token = expr.intexpr_gettok(str); + expr.intexpr_L(str); + result = expr; + return result; + } + + private static final String Int = "(-*[\\d]+)"; + private static final String Range = "\\[(-*[\\d]+),(-*[\\d]+)\\]";//"\\[([\\w-]+?),([\\w-]+?)\\]"; + private static final String probabilityValue = "(0\\.[0-9]+)"; +} \ No newline at end of file diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Variable.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Variable.java new file mode 100644 index 000000000..3c4c06747 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/Variable.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn; + +import java.util.ArrayList; +import java.util.Properties; + +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.InequalityVariable; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Variable { + + protected String name; + + private String type; + + protected String initValue; + + private String initRate; + + private String port; + + // For continuous variables, a list of inequality variables + // that contain this continuous variable. + protected ArrayList inequalities; + + public Variable(String name, String type) { + this.name = name; + this.type = type; + } + + public Variable(String name, String type, String initValue) { + this.name = name; + this.type = type; + this.initValue = initValue; + } + + public Variable(String name, String type, Properties initCond) { + if (type.equals(CONTINUOUS)) { + this.name = name; + this.type = type; + this.initValue = initCond.getProperty("value"); + this.initRate = initCond.getProperty("rate"); + } + } + + public Variable(String name, String type, Properties initCond, String port) { + if (type.equals(CONTINUOUS)) { + this.name = name; + this.type = type; + this.initValue = initCond.getProperty("value"); + this.initRate = initCond.getProperty("rate"); + this.port = port; + } + } + + public Variable(String name, String type, String initValue, String port) { + this.name = name; + this.type = type; + this.initValue = initValue; + this.port = port; + } + + public void addInitValue(String initValue) { + this.initValue = initValue; + } + + public void addInitRate(String initRate) { + this.initRate = initRate; + } + + public void addInitCond(Properties initCond) { + if (type.equals(CONTINUOUS)) { + this.initValue = initCond.getProperty("value"); + this.initRate = initCond.getProperty("rate"); + } + } + + public String getName() { + return name; + } + + public String getInitValue() { + return initValue; + } + + public String getInitRate() { + return initRate; + } + + public boolean isInput() { + if (port != null) { + return port.equals(INPUT); + } + return false; + } + + public boolean isOutput() { + if (port != null) { + return port.equals(OUTPUT); + } + return false; + } + + public boolean isInternal() { + if (port != null) { + return port.equals(INTERNAL); + } + return true; + } + + public String getPort() { + return port; + } + + public String getType() { + return type; + } + + public void setPort(String newPort) { + port = newPort; + } + + @Override + public String toString() { + return name; + } + + @Override + public boolean equals(Object var) { + return name.equals(var.toString()); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((initRate == null) ? 0 : initRate.hashCode()); + result = prime * result + + ((initValue == null) ? 0 : initValue.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((port == null) ? 0 : port.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + return result; + } + + /** + * Get the list of inequality variables that reference this continuous + * variable. + * @return + * A list of all the inequality variables that reference this continuous + * variable. + */ + public ArrayList getInequalities(){ + return inequalities; + } + + /** + * Add an inequality variable that references this continuous variable. + * @param inVar + * The InequalityVariable to add. + */ + public void addInequalityVariable(InequalityVariable inVar){ + if(inequalities == null){ + inequalities = new ArrayList(); + } + inequalities.add(inVar); + } + + public static final String BOOLEAN = "boolean"; + + public static final String INTEGER = "integer"; + + public static final String CONTINUOUS = "continuous"; + + public static final String INPUT = "input"; + + public static final String OUTPUT = "output"; + + public static final String INTERNAL = "internal"; + +} \ No newline at end of file diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/AbstractionProperty.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/AbstractionProperty.java new file mode 100644 index 000000000..abe481249 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/AbstractionProperty.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn.properties; + +import javax.swing.DefaultListModel; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class AbstractionProperty { + + public String xform0 = "Merge Parallel Places - simplification", + xform1 = "Remove Place in Self-Loop - simplification", + xform3 = "Remove Transitions with Single Place in Postset - simplification", + xform4 = "Remove Transitions with Single Place in Preset - simplification", + xform5 = "Merge Transitions with Same Preset and Postset - simplification", + xform6 = "Merge Transitions with Same Preset - simplification", + xform7 = "Merge Transitions with Same Postset - simplification", + xform8 = "Local Assignment Propagation - simplification", + xform9 = "Remove Write Before Write - simplification", + xform10 = "Simplify Expressions - simplification", + xform11 = "Constant False Enabling Conditions - simplification", + xform12 = "Abstract Assignments to the Same Variable - abstraction", + xform13 = "Remove Unread Variables - abstraction", + xform14 = "Remove Dead Places - simplification", + xform15 = "Remove Dead Transitions - simplification", + xform16 = "Constant True Enabling Conditions - simplification", + xform17 = "Eliminate Dominated Transitions - simplification", + xform18 = "Remove Unread Variables - simplification", + xform19 = "Correlated Variables - simplification", + xform20 = "Remove Arc after Failure Transitions - simplification", + xform21 = "Timing Bound Normalization - abstraction", + xform22 = "Remove Vacuous Transitions - simplification", + xform23 = "Remove Vacuous Transitions - abstraction", + xform24 = "Remove Pairwise Write Before Write - simplification", + xform25 = "Propagate Constant Variable Values - simplifiction", + xform26 = "Remove Dangling Transitions - simplification", + xform27 = "Combine Parallel Transitions - simplification", + xform28 = "Combine Parallel Transitions - abstraction", + xform29 = "Remove Uninteresting Variables - simplification", + xform30 = "Remove Uninteresting Transitions - simplification", + xform31 = "Simplify Uniform Expressions - abstraction"; + + public String[] transforms = { xform12, xform28, xform27, xform11, xform16, + xform19, xform17, xform8, xform0, xform7, xform6, xform5, xform25, xform20, + xform26, xform14, xform15, xform24, xform1, xform3, xform4, + xform30, xform29, xform13, xform18, xform23, xform22, xform9, + xform10, xform31, xform21 }; + + public DefaultListModel listModel, absListModel, preAbsModel, loopAbsModel, + postAbsModel; + + public String maxIter, factor, field; + + boolean verification, simplify, abstractLhpn; + + public AbstractionProperty() + { + listModel = new DefaultListModel(); + // Creates Abstraction List + preAbsModel = new DefaultListModel(); + loopAbsModel = new DefaultListModel(); + postAbsModel = new DefaultListModel(); + maxIter = ""; factor = ""; field = ""; + simplify = true; + verification = true; + } + + public String[] getIntVars() { + String[] intVars = new String[listModel.getSize()]; + for (int i = 0; i < listModel.getSize(); i++) { + if (listModel.elementAt(i) != null) { + intVars[i] = listModel.elementAt(i).toString(); + } + } + return intVars; + } + + public void viewCircuit() { + String[] getFilename; + if (field.trim().equals("")) { + } else { + getFilename = new String[1]; + getFilename[0] = field.trim(); + } + } + + public boolean isSimplify() { + if (verification) { + return true; + } + if (simplify + || abstractLhpn) { + return true; + } + return false; + } + + public boolean isAbstract() { + if (verification) { + return true; + } + return abstractLhpn; + } + + public Integer getNormFactor() { + Integer factor; + try { + factor = Integer.parseInt(this.factor); + } + catch (NumberFormatException e) { + factor = -1; + } + return factor; + } + + public Integer maxIterations() { + return Integer.parseInt(maxIter); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/BuildProperty.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/BuildProperty.java new file mode 100644 index 000000000..88cd73f59 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/BuildProperty.java @@ -0,0 +1,1103 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.lpn.properties; + +import java.awt.List; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Properties; + +import org.antlr.runtime.*; +import org.antlr.runtime.tree.*; + +import edu.utah.ece.async.ibiosim.dataModels.util.exceptions.BioSimException; +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Translator; +import edu.utah.ece.async.lema.verification.lpn.Variable; + +import org.antlr.runtime.CharStream; +import org.antlr.runtime.CommonTokenStream; +import org.antlr.runtime.RecognitionException; +import org.antlr.runtime.TokenStream; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class BuildProperty { + //public static JFrame frame; + static int numPlaces=0; + static int numTransitions=0; + static int numFailTransitions=0; + static int numFailPlaces=0; + static int numStartPlaces=0; + static int numEndPlaces=0; + static String pFirst = "p0"; + static String pLast =""; + static boolean loop = false; + + static List list = new List(); + public static void buildProperty(String propFileName) throws IOException, RecognitionException, BioSimException { + + //String propertyId = JOptionPane.showInputDialog(frame, "Enter the SVA property name:", "Model ID", JOptionPane.PLAIN_MESSAGE); + //System.out.println(propertyId); + //if (propertyId!=null){ + //String property = JOptionPane.showInputDialog(frame, "Enter the SVA property:", "Model", JOptionPane.PLAIN_MESSAGE); + //CharStream charStream = new ANTLRStringStream(" wait(omega > 2.2, 20);\r\n" + + //"assert(abc, 20); "); + numPlaces=0; + numTransitions=0; + numFailTransitions=0; + numFailPlaces=0; + numStartPlaces=0; + numEndPlaces=0; + + + + LPN lpn = new LPN(); + //lpn.load(propFileName); + + String lpnFileString= propFileName.substring(0, propFileName.length()-4); + String lpnFileName = lpnFileString.concat("lpn"); + File lpnFile = new File(lpnFileName); + lpnFile.createNewFile(); + + //String[] lpnPath = lpnFileName.split(separator); + //System.out.println("No of places : "+numPlaces); + + //System.out.println("No of places : "+numPlaces); + + BufferedReader input = new BufferedReader(new FileReader(propFileName)); + + String line = input.readLine(); + + //StringBuffer sb2 = new StringBuffer(line); + StringBuffer sb = new StringBuffer(line); + //LhpnFile lpn = new LhpnFile(); + + while(line!=null){ + + line=input.readLine(); + sb.append(line); + + } + input.close(); + + String property = sb.toString(); + //System.out.println("property: "+property+"\n"); + CharStream charStream = new ANTLRStringStream(property); + PropertyLexer lexer = new PropertyLexer(charStream); + TokenStream tokenStream = new CommonTokenStream(lexer); + PropertyParser parser = new PropertyParser(tokenStream); + PropertyParser.program_return program; + try { + program = parser.program(); + } + catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + //JOptionPane.showMessageDialog(Gui.frame, "Error parsing property file, check console.", "Parse Error", JOptionPane.ERROR_MESSAGE); + return; + } + if (parser.getNumberOfSyntaxErrors()>0) { + throw new BioSimException("Error parsing property file, check console.", "Parse Error"); + } + //System.out.println("tree: "+((Tree)program.tree).toStringTree()+"\n"); + + CommonTree r0 = program.tree; + //System.out.println("parent :"+program.start.getText()); + //int number = r0.getChildCount(); + //System.out.println("NUMBER : "+number+"\n"); + //printTree(r0, number); + generateFile(r0, lpn,lpnFileName); + } + + public static void generateFile(CommonTree r0, LPN lpn, String lpnFileName) throws BioSimException{ + LPN lpnFinal = new LPN(); + File lpnFile = new File(".lpn"); + try { + lpnFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + lpnFinal = generateLPN(r0, lpn, false, null); + if(loop){ + lpnFinal.addTransition("t" + numTransitions); + lpnFinal.changeDelay("t" + numTransitions, "0"); + numTransitions++; + lpnFinal.addMovement(pLast,"t" +(numTransitions-1)); + lpnFinal.addMovement("t" +(numTransitions-1), pFirst); + loop=false; + } + + } catch (IOException e) { + e.printStackTrace(); + } + lpnFinal.save(lpnFileName); + Translator t1 = new Translator(); + t1.convertLPN2SBML(lpnFileName, ""); + t1.setFilename(lpnFileName.replace(".lpn", ".xml")); + t1.outputSBML(); + } + + public static void printTree(CommonTree t, int number) { + + if ( t != null ) { + StringBuffer sb = new StringBuffer(number); + for ( int i = 0; i < number; i++ ) + sb = sb.append(" "); + for ( int i = 0; i < t.getChildCount(); i++ ) { + System.out.println(sb.toString() + t.getChild(i).toString()); + printTree((CommonTree)t.getChild(i), number+1); + } + } + } + + public static LPN generateLPN(CommonTree t, LPN lpn2, boolean recursiveCall, String stayConditions) throws IOException { + + String enablingCond=""; + String delay=""; + String varType = " "; + String varName = ""; + + LPN lpnObj= lpn2; + if ( t != null ) { + int childCount=0; + if(recursiveCall){ + childCount=1; + } + else{ + childCount= t.getChildCount(); + } + + //System.out.println("child count is : "+t.getChildCount()); + for(int i=0;i 0){ + + // Check if the zero-th child is a sensitivity list. + CommonTree theList = (CommonTree) switchCaseTree.getChild(0); + if(theList.getType() == + edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.LPARA){ + + sensitivityList = new String[theList.getChildCount()]; + sensitivityVariables = new String[theList.getChildCount()]; + + // Loop through the list gathering the elements. + int elementCount = 0; + for(Object obj : theList.getChildren()){ + + CommonTree listElement = (CommonTree) obj; + + sensitivityList[elementCount] = + generateExpression(listElement); + + String storedVariableType = lpnObj.getVariable( + sensitivityList[elementCount]).getType(); + + String storedVariable = "_" + sensitivityList[elementCount]; + + // Add the stay condition. + if(stayConditions != null & elementCount > 0){ + stayConditions += "&"; + }else{ + stayConditions = ""; + } + stayConditions += "(" + sensitivityList[elementCount] + "=" + + storedVariable + ")"; + + sensitivityVariables[elementCount] = storedVariable; + + if(storedVariableType == "boolean"){ + // lpnObj.addBoolean(sensitivityVariables[elementCount], "0"); + lpnObj.addInput(sensitivityVariables[elementCount], storedVariableType, "0"); + } + else if (storedVariableType == "integer"){ + lpnObj.addInteger(sensitivityVariables[elementCount], "0"); + } + else if (storedVariableType == "discrete"){ + lpnObj.addInteger(sensitivityVariables[elementCount], "0"); + } + else if (storedVariableType == "continuous"){ + Properties initCond = new Properties(); + initCond.put("value", "0"); + initCond.put("rate", "0"); + lpnObj.addContinuousInput(sensitivityVariables[elementCount], initCond); + } + + elementCount++; + } + + // Remove the sensitivity list. + switchCaseTree.deleteChild(0); + + if(numPlaces == 0){ + lpnObj.addPlace("p" + 0, true); + numPlaces++; + } + + // Create the transition that stores the variables in the the list. + lpnObj.addTransition("t" + numTransitions); + lpnObj.changeDelay("t" + numTransitions, "0"); + numTransitions++; + lpnObj.addPlace("p" + numPlaces, false); + numPlaces++; + lpnObj.addMovement("p" + senalways_pFirst, "t" + (numTransitions-1)); + lpnObj.addMovement("t" + (numTransitions-1), "p" + (numPlaces-1)); + + for(int k=0; k" +string2); + //System.out.println("String in GET :"+result); + break; + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.AND : + string1= generateExpression((CommonTree)newChild.getChild(0)); + string2= generateExpression((CommonTree)newChild.getChild(1)); + result= ("("+string1 + ")&(" +string2+")"); + //result= (string1 + "&" +string2); + break; + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.DIV : + string1= generateExpression((CommonTree)newChild.getChild(0)); + string2= generateExpression((CommonTree)newChild.getChild(1)); + result= (string1 + "/" +string2); + //System.out.println("result2 :"+result); + break; + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.EQUAL : + string1= generateExpression((CommonTree)newChild.getChild(0)); + string2= generateExpression((CommonTree)newChild.getChild(1)); + result= (string1 + "=" +string2); + //System.out.println("result2 :"+result); + break; + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.GETEQ : + string1= generateExpression((CommonTree)newChild.getChild(0)); + string2= generateExpression((CommonTree)newChild.getChild(1)); + result= (string1 + ">=" +string2); + + break; + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.LET : + string1= generateExpression((CommonTree)newChild.getChild(0)); + string2= generateExpression((CommonTree)newChild.getChild(1)); + result= (string1 + "<" +string2); + //System.out.println("result2 :"+result); + break; + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.LETEQ : + string1= generateExpression((CommonTree)newChild.getChild(0)); + string2= generateExpression((CommonTree)newChild.getChild(1)); + result= (string1 + "<=" +string2); + //System.out.println("result2 :"+result); + break; + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.MINUS : + string1= generateExpression((CommonTree)newChild.getChild(0)); + string2= generateExpression((CommonTree)newChild.getChild(1)); + result= (string1 + "-" +string2); + //System.out.println("result2 :"+result); + break; + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.MOD : + string1= generateExpression((CommonTree)newChild.getChild(0)); + string2= generateExpression((CommonTree)newChild.getChild(1)); + result= (string1 + "%" +string2); + //System.out.println("result2 :"+result); + break; + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.MULT : + string1= generateExpression((CommonTree)newChild.getChild(0)); + string2= generateExpression((CommonTree)newChild.getChild(1)); + result= (string1 + "*" +string2); + //System.out.println("result2 :"+result); + break; + + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.NOT : + string1= generateExpression((CommonTree)newChild.getChild(0)); + result= ("~(" +string1+")"); + //result= "~"+string1; + //System.out.println("String in NOT :"+result); + break; + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.NOT_EQUAL : + string1= generateExpression((CommonTree)newChild.getChild(0)); + string2= generateExpression((CommonTree)newChild.getChild(1)); + result= (string1 + "!=" +string2); + //System.out.println("result2 :"+result); + break; + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.OR : + string1= generateExpression((CommonTree)newChild.getChild(0)); + string2= generateExpression((CommonTree)newChild.getChild(1)); + result= (string1 + "|" +string2); + //System.out.println("result2 :"+result); + break; + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.PLUS : + string1= generateExpression((CommonTree)newChild.getChild(0)); + string2= generateExpression((CommonTree)newChild.getChild(1)); + result= (string1 + " + " +string2); + //System.out.println("result2 :"+result); + break; + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.SAMEAS : + string1= generateExpression((CommonTree)newChild.getChild(0)); + string2= generateExpression((CommonTree)newChild.getChild(1)); + result= (string1 + "=" +string2); + //System.out.println("String in SAMEAS :"+result); + break; + + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.LPARA : + string1= generateExpression((CommonTree)newChild.getChild(0)); + string2= generateExpression((CommonTree)newChild.getChild(1)); + result= "("; + break; + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.RPARA : + string1= generateExpression((CommonTree)newChild.getChild(0)); + string2= generateExpression((CommonTree)newChild.getChild(1)); + result= ")"; + //System.out.println("String in SAMEAS :"+result); + break; + case edu.utah.ece.async.lema.verification.lpn.properties.PropertyLexer.UNIFORM : + result= newChild.toString(); + //System.out.println("String in UNIFORM :"+result); + break; + default : + break; + } + + } + return result; + } + +} \ No newline at end of file diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/Property.g b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/Property.g new file mode 100644 index 000000000..4674705ad --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/Property.g @@ -0,0 +1,396 @@ +grammar Property; + + +options { + language = Java; + output = AST; + ASTLabelType = CommonTree; + +} + +@header { + package lpn.parser.properties; + //import lpn.parser.LhpnFile; + //package antlrPackage; +} + +@lexer::header { + package lpn.parser.properties; + //package antlrPackage; +} + + + +program + :property + ; + +property +: 'property'^ ID LCURL! (declaration)* (statement)* RCURL! +; + +declaration + :BOOLEAN^ ID (COMMA! ID)* SEMICOL! + | REAL^ ID (COMMA! ID)* SEMICOL! + | INTEGER^ ID (COMMA! ID)* SEMICOL! + ; + +SENALWAYS + : 'senalways' + ; + +ALWAYS +: 'always' +; + +BOOLEAN +:'boolean' +; + +REAL +:'real' +; + +INTEGER +:'int' +; + + +WAIT +:'wait' +; + +WAIT_DELAY +:'waitDelay' +; + +NOT +: '~' +; + +MOD +:'%' +; + + +AND +:'&' +; + +OR +:'|' +; + + +ASSERT +:'assert' +; + + +IF +:'if' +; + + +END +:'end' +; + + +ELSEIF +:'else if' +; + +ELSE +:'else' +; + +WAIT_STABLE +:'waitStable' +; + +ASSERT_STABLE +:'assertStable' +; + +ASSERT_UNTIL +:'assertUntil' +; + + +WAIT_POSEDGE +: 'waitPosedge' +; + + +ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* + ; + +INT : '0'..'9'+ + + ; +FLOAT + : ('0'..'9')+ '.' ('0'..'9')* EXPONENT? + | '.' ('0'..'9')+ EXPONENT? + | ('0'..'9')+ EXPONENT + ; + +COMMENT + : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;} + | '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;} + ; + +WS : ( ' ' + | '\t' + | '\r' + | '\n' + |'\r\n' + ) {$channel=HIDDEN;} + ; + + + +STRING + : '\'' ( ESC_SEQ | ~('\\'|'\'') )* '\'' + ; + + +fragment +EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ; + +fragment +HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ; + +fragment +ESC_SEQ + : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') + | UNICODE_ESC + | OCTAL_ESC + ; + +fragment +OCTAL_ESC + : '\\' ('0'..'3') ('0'..'7') ('0'..'7') + | '\\' ('0'..'7') ('0'..'7') + | '\\' ('0'..'7') + ; + +fragment +UNICODE_ESC + : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT + ; + + + + +PLUS +:'+' +; + +MINUS +: '-' +; + + +MULT +:'*' +; + +DIV +:'/' +; + +DASH +:'***' +; +EQUAL +:'=' +; + + +NOT_EQUAL +:'!=' +; + +GET +:'>' +; + +LET +:'<' +; + +GETEQ +:'>=' +; +LETEQ +:'<=' +; + + +SAMEAS +:'==' +; + + + +LPARA +:'(' +; + +RPARA +:')' +; + +LCURL +:'{' +; + +RCURL +:'}' +; + + + +SEMICOL +:';' +; + +COMMA +:',' +; +UNIFORM +:'uniform('INT','INT')' +; + +booleanNegationExpression +: (NOT^)* constantValue +//: (NOT^)* (LPARA!)* relationalExpression (RPARA!)* +; + +always_statement + : ALWAYS^ LCURL! (statement)* RCURL! //SEMICOL! + ; + +senalways_statement + : SENALWAYS^ (sensitivityList)? LCURL! (statement)* RCURL! + ; + +sensitivityList + : (LPARA^ ID (COMMA! ID)* RPARA!) + ; + +signExpression +:(PLUS^|MINUS^)* booleanNegationExpression +//:(PLUS^|MINUS^)* constantValue +; +multiplyingExpression + : signExpression ((MULT^|DIV^|MOD^) signExpression)* + ; + + + +addingExpression + : multiplyingExpression ((PLUS^|MINUS^) multiplyingExpression)* + ; + + +relationalExpression + : addingExpression ((EQUAL^|NOT_EQUAL^|GET^|GETEQ^|LET^|LETEQ^|SAMEAS^) addingExpression)* + ; + +logicalExpression + : relationalExpression ((AND^|OR^) relationalExpression)* + ; +//logicalExpression + // : relationalExpression ((AND^|OR^) relationalExpression)* +// ; + +unaryExpression + : (NOT^)* LPARA! logicalExpression RPARA! + // : (NOT^)* logicalExpression + ; + +combinationalExpression +: unaryExpression ((AND^|OR^) unaryExpression)* +; +expression + //: relational + //:constantValue + //|primitiveElement + //|addingExpression + //|multiplyingExpression + //: unaryExpression + // | logicalExpression + :combinationalExpression + | logicalExpression + ; + + +constantValue + : INT | ID | UNIFORM + ; + +wait_statement + : WAIT^ LPARA! expression RPARA! SEMICOL! +// | WAIT^ LPARA! expression COMMA! expression (GET expression)* RPARA! SEMICOL! + | WAIT^ LPARA! expression COMMA! expression RPARA! SEMICOL! + ; + +wait_delay_statement + : WAIT_DELAY^ LPARA! expression RPARA! SEMICOL! + ; + +assert_statement + : ASSERT^ LPARA! expression COMMA! expression RPARA! SEMICOL! + ; + +if_statement + : IF^ if_part + ; + +if_part + : LPARA!expression RPARA! LCURL! (statement)* RCURL! (else_if)* (else_part)* + ; + +else_if + : ELSEIF^ LPARA!expression RPARA! LCURL! (statement)* RCURL! + ; + +else_part + :ELSE^ LCURL! (statement)* RCURL! + ; + +waitStable_statement +:WAIT_STABLE^ LPARA! expression COMMA! expression RPARA! SEMICOL! +; +assertUntil_statement +:ASSERT_UNTIL^ LPARA! expression COMMA! expression RPARA! SEMICOL! +; + +edge_statement +: WAIT_POSEDGE^ LPARA! expression RPARA! SEMICOL! +; +assertStable_statement +:ASSERT_STABLE^ LPARA! expression COMMA! expression RPARA! SEMICOL! +; + + +//waitPosedge_statement +//:WAIT_POSEDGE^ LPARA! expression RPARA! SEMICOL! +//; + +statement + :wait_statement + |wait_delay_statement + |assert_statement + |if_statement + |waitStable_statement + |assertUntil_statement + |always_statement + |assertStable_statement + |edge_statement + |senalways_statement + ; + + diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/PropertyLexer.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/PropertyLexer.java new file mode 100644 index 000000000..323683056 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/lpn/properties/PropertyLexer.java @@ -0,0 +1,2505 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +// $ANTLR 3.5 /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g 2016-09-01 11:02:46 + +package edu.utah.ece.async.lema.verification.lpn.properties; + +import org.antlr.runtime.*; +import java.util.Stack; +import java.util.List; +import java.util.ArrayList; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +@SuppressWarnings("all") +public class PropertyLexer extends Lexer { + public static final int EOF=-1; + public static final int T__54=54; + public static final int ALWAYS=4; + public static final int AND=5; + public static final int ASSERT=6; + public static final int ASSERT_STABLE=7; + public static final int ASSERT_UNTIL=8; + public static final int BOOLEAN=9; + public static final int COMMA=10; + public static final int COMMENT=11; + public static final int DASH=12; + public static final int DIV=13; + public static final int ELSE=14; + public static final int ELSEIF=15; + public static final int END=16; + public static final int EQUAL=17; + public static final int ESC_SEQ=18; + public static final int EXPONENT=19; + public static final int FLOAT=20; + public static final int GET=21; + public static final int GETEQ=22; + public static final int HEX_DIGIT=23; + public static final int ID=24; + public static final int IF=25; + public static final int INT=26; + public static final int INTEGER=27; + public static final int LCURL=28; + public static final int LET=29; + public static final int LETEQ=30; + public static final int LPARA=31; + public static final int MINUS=32; + public static final int MOD=33; + public static final int MULT=34; + public static final int NOT=35; + public static final int NOT_EQUAL=36; + public static final int OCTAL_ESC=37; + public static final int OR=38; + public static final int PLUS=39; + public static final int RCURL=40; + public static final int REAL=41; + public static final int RPARA=42; + public static final int SAMEAS=43; + public static final int SEMICOL=44; + public static final int SENALWAYS=45; + public static final int STRING=46; + public static final int UNICODE_ESC=47; + public static final int UNIFORM=48; + public static final int WAIT=49; + public static final int WAIT_DELAY=50; + public static final int WAIT_POSEDGE=51; + public static final int WAIT_STABLE=52; + public static final int WS=53; + + // delegates + // delegators + public Lexer[] getDelegates() { + return new Lexer[] {}; + } + + public PropertyLexer() {} + public PropertyLexer(CharStream input) { + this(input, new RecognizerSharedState()); + } + public PropertyLexer(CharStream input, RecognizerSharedState state) { + super(input,state); + } + @Override public String getGrammarFileName() { return "/Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g"; } + + // $ANTLR start "T__54" + public final void mT__54() throws RecognitionException { + try { + int _type = T__54; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:12:7: ( 'property' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:12:9: 'property' + { + match("property"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "T__54" + + // $ANTLR start "SENALWAYS" + public final void mSENALWAYS() throws RecognitionException { + try { + int _type = SENALWAYS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:39:3: ( 'senalways' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:39:5: 'senalways' + { + match("senalways"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "SENALWAYS" + + // $ANTLR start "ALWAYS" + public final void mALWAYS() throws RecognitionException { + try { + int _type = ALWAYS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:43:3: ( 'always' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:43:3: 'always' + { + match("always"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "ALWAYS" + + // $ANTLR start "BOOLEAN" + public final void mBOOLEAN() throws RecognitionException { + try { + int _type = BOOLEAN; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:47:2: ( 'boolean' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:47:2: 'boolean' + { + match("boolean"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "BOOLEAN" + + // $ANTLR start "REAL" + public final void mREAL() throws RecognitionException { + try { + int _type = REAL; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:51:2: ( 'real' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:51:2: 'real' + { + match("real"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "REAL" + + // $ANTLR start "INTEGER" + public final void mINTEGER() throws RecognitionException { + try { + int _type = INTEGER; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:55:2: ( 'int' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:55:2: 'int' + { + match("int"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "INTEGER" + + // $ANTLR start "WAIT" + public final void mWAIT() throws RecognitionException { + try { + int _type = WAIT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:60:2: ( 'wait' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:60:2: 'wait' + { + match("wait"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "WAIT" + + // $ANTLR start "WAIT_DELAY" + public final void mWAIT_DELAY() throws RecognitionException { + try { + int _type = WAIT_DELAY; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:64:2: ( 'waitDelay' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:64:2: 'waitDelay' + { + match("waitDelay"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "WAIT_DELAY" + + // $ANTLR start "NOT" + public final void mNOT() throws RecognitionException { + try { + int _type = NOT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:68:3: ( '~' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:68:3: '~' + { + match('~'); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "NOT" + + // $ANTLR start "MOD" + public final void mMOD() throws RecognitionException { + try { + int _type = MOD; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:72:2: ( '%' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:72:2: '%' + { + match('%'); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "MOD" + + // $ANTLR start "AND" + public final void mAND() throws RecognitionException { + try { + int _type = AND; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:77:2: ( '&' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:77:2: '&' + { + match('&'); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "AND" + + // $ANTLR start "OR" + public final void mOR() throws RecognitionException { + try { + int _type = OR; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:81:2: ( '|' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:81:2: '|' + { + match('|'); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "OR" + + // $ANTLR start "ASSERT" + public final void mASSERT() throws RecognitionException { + try { + int _type = ASSERT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:86:2: ( 'assert' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:86:2: 'assert' + { + match("assert"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "ASSERT" + + // $ANTLR start "IF" + public final void mIF() throws RecognitionException { + try { + int _type = IF; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:91:2: ( 'if' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:91:2: 'if' + { + match("if"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "IF" + + // $ANTLR start "END" + public final void mEND() throws RecognitionException { + try { + int _type = END; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:96:2: ( 'end' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:96:2: 'end' + { + match("end"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "END" + + // $ANTLR start "ELSEIF" + public final void mELSEIF() throws RecognitionException { + try { + int _type = ELSEIF; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:101:2: ( 'else if' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:101:2: 'else if' + { + match("else if"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "ELSEIF" + + // $ANTLR start "ELSE" + public final void mELSE() throws RecognitionException { + try { + int _type = ELSE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:105:2: ( 'else' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:105:2: 'else' + { + match("else"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "ELSE" + + // $ANTLR start "WAIT_STABLE" + public final void mWAIT_STABLE() throws RecognitionException { + try { + int _type = WAIT_STABLE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:109:2: ( 'waitStable' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:109:2: 'waitStable' + { + match("waitStable"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "WAIT_STABLE" + + // $ANTLR start "ASSERT_STABLE" + public final void mASSERT_STABLE() throws RecognitionException { + try { + int _type = ASSERT_STABLE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:113:2: ( 'assertStable' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:113:2: 'assertStable' + { + match("assertStable"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "ASSERT_STABLE" + + // $ANTLR start "ASSERT_UNTIL" + public final void mASSERT_UNTIL() throws RecognitionException { + try { + int _type = ASSERT_UNTIL; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:117:2: ( 'assertUntil' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:117:2: 'assertUntil' + { + match("assertUntil"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "ASSERT_UNTIL" + + // $ANTLR start "WAIT_POSEDGE" + public final void mWAIT_POSEDGE() throws RecognitionException { + try { + int _type = WAIT_POSEDGE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:122:3: ( 'waitPosedge' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:122:3: 'waitPosedge' + { + match("waitPosedge"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "WAIT_POSEDGE" + + // $ANTLR start "ID" + public final void mID() throws RecognitionException { + try { + int _type = ID; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:126:5: ( ( 'a' .. 'z' | 'A' .. 'Z' | '_' ) ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )* ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:126:7: ( 'a' .. 'z' | 'A' .. 'Z' | '_' ) ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )* + { + if ( (input.LA(1) >= 'A' && input.LA(1) <= 'Z')||input.LA(1)=='_'||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:126:31: ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )* + loop1: + while (true) { + int alt1=2; + int LA1_0 = input.LA(1); + if ( ((LA1_0 >= '0' && LA1_0 <= '9')||(LA1_0 >= 'A' && LA1_0 <= 'Z')||LA1_0=='_'||(LA1_0 >= 'a' && LA1_0 <= 'z')) ) { + alt1=1; + } + + switch (alt1) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g: + { + if ( (input.LA(1) >= '0' && input.LA(1) <= '9')||(input.LA(1) >= 'A' && input.LA(1) <= 'Z')||input.LA(1)=='_'||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + } + break; + + default : + break loop1; + } + } + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "ID" + + // $ANTLR start "INT" + public final void mINT() throws RecognitionException { + try { + int _type = INT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:129:5: ( ( '0' .. '9' )+ ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:129:7: ( '0' .. '9' )+ + { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:129:7: ( '0' .. '9' )+ + int cnt2=0; + loop2: + while (true) { + int alt2=2; + int LA2_0 = input.LA(1); + if ( ((LA2_0 >= '0' && LA2_0 <= '9')) ) { + alt2=1; + } + + switch (alt2) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g: + { + if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + } + break; + + default : + if ( cnt2 >= 1 ) break loop2; + EarlyExitException eee = new EarlyExitException(2, input); + throw eee; + } + cnt2++; + } + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "INT" + + // $ANTLR start "FLOAT" + public final void mFLOAT() throws RecognitionException { + try { + int _type = FLOAT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:133:5: ( ( '0' .. '9' )+ '.' ( '0' .. '9' )* ( EXPONENT )? | '.' ( '0' .. '9' )+ ( EXPONENT )? | ( '0' .. '9' )+ EXPONENT ) + int alt9=3; + alt9 = dfa9.predict(input); + switch (alt9) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:133:9: ( '0' .. '9' )+ '.' ( '0' .. '9' )* ( EXPONENT )? + { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:133:9: ( '0' .. '9' )+ + int cnt3=0; + loop3: + while (true) { + int alt3=2; + int LA3_0 = input.LA(1); + if ( ((LA3_0 >= '0' && LA3_0 <= '9')) ) { + alt3=1; + } + + switch (alt3) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g: + { + if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + } + break; + + default : + if ( cnt3 >= 1 ) break loop3; + EarlyExitException eee = new EarlyExitException(3, input); + throw eee; + } + cnt3++; + } + + match('.'); + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:133:25: ( '0' .. '9' )* + loop4: + while (true) { + int alt4=2; + int LA4_0 = input.LA(1); + if ( ((LA4_0 >= '0' && LA4_0 <= '9')) ) { + alt4=1; + } + + switch (alt4) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g: + { + if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + } + break; + + default : + break loop4; + } + } + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:133:37: ( EXPONENT )? + int alt5=2; + int LA5_0 = input.LA(1); + if ( (LA5_0=='E'||LA5_0=='e') ) { + alt5=1; + } + switch (alt5) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:133:37: EXPONENT + { + mEXPONENT(); + + } + break; + + } + + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:134:9: '.' ( '0' .. '9' )+ ( EXPONENT )? + { + match('.'); + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:134:13: ( '0' .. '9' )+ + int cnt6=0; + loop6: + while (true) { + int alt6=2; + int LA6_0 = input.LA(1); + if ( ((LA6_0 >= '0' && LA6_0 <= '9')) ) { + alt6=1; + } + + switch (alt6) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g: + { + if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + } + break; + + default : + if ( cnt6 >= 1 ) break loop6; + EarlyExitException eee = new EarlyExitException(6, input); + throw eee; + } + cnt6++; + } + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:134:25: ( EXPONENT )? + int alt7=2; + int LA7_0 = input.LA(1); + if ( (LA7_0=='E'||LA7_0=='e') ) { + alt7=1; + } + switch (alt7) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:134:25: EXPONENT + { + mEXPONENT(); + + } + break; + + } + + } + break; + case 3 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:135:9: ( '0' .. '9' )+ EXPONENT + { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:135:9: ( '0' .. '9' )+ + int cnt8=0; + loop8: + while (true) { + int alt8=2; + int LA8_0 = input.LA(1); + if ( ((LA8_0 >= '0' && LA8_0 <= '9')) ) { + alt8=1; + } + + switch (alt8) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g: + { + if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + } + break; + + default : + if ( cnt8 >= 1 ) break loop8; + EarlyExitException eee = new EarlyExitException(8, input); + throw eee; + } + cnt8++; + } + + mEXPONENT(); + + } + break; + + } + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "FLOAT" + + // $ANTLR start "COMMENT" + public final void mCOMMENT() throws RecognitionException { + try { + int _type = COMMENT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:139:5: ( '//' (~ ( '\\n' | '\\r' ) )* ( '\\r' )? '\\n' | '/*' ( options {greedy=false; } : . )* '*/' ) + int alt13=2; + int LA13_0 = input.LA(1); + if ( (LA13_0=='/') ) { + int LA13_1 = input.LA(2); + if ( (LA13_1=='/') ) { + alt13=1; + } + else if ( (LA13_1=='*') ) { + alt13=2; + } + + else { + int nvaeMark = input.mark(); + try { + input.consume(); + NoViableAltException nvae = + new NoViableAltException("", 13, 1, input); + throw nvae; + } finally { + input.rewind(nvaeMark); + } + } + + } + + else { + NoViableAltException nvae = + new NoViableAltException("", 13, 0, input); + throw nvae; + } + + switch (alt13) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:139:9: '//' (~ ( '\\n' | '\\r' ) )* ( '\\r' )? '\\n' + { + match("//"); + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:139:14: (~ ( '\\n' | '\\r' ) )* + loop10: + while (true) { + int alt10=2; + int LA10_0 = input.LA(1); + if ( ((LA10_0 >= '\u0000' && LA10_0 <= '\t')||(LA10_0 >= '\u000B' && LA10_0 <= '\f')||(LA10_0 >= '\u000E' && LA10_0 <= '\uFFFF')) ) { + alt10=1; + } + + switch (alt10) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g: + { + if ( (input.LA(1) >= '\u0000' && input.LA(1) <= '\t')||(input.LA(1) >= '\u000B' && input.LA(1) <= '\f')||(input.LA(1) >= '\u000E' && input.LA(1) <= '\uFFFF') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + } + break; + + default : + break loop10; + } + } + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:139:28: ( '\\r' )? + int alt11=2; + int LA11_0 = input.LA(1); + if ( (LA11_0=='\r') ) { + alt11=1; + } + switch (alt11) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:139:28: '\\r' + { + match('\r'); + } + break; + + } + + match('\n'); + _channel=HIDDEN; + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:140:9: '/*' ( options {greedy=false; } : . )* '*/' + { + match("/*"); + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:140:14: ( options {greedy=false; } : . )* + loop12: + while (true) { + int alt12=2; + int LA12_0 = input.LA(1); + if ( (LA12_0=='*') ) { + int LA12_1 = input.LA(2); + if ( (LA12_1=='/') ) { + alt12=2; + } + else if ( ((LA12_1 >= '\u0000' && LA12_1 <= '.')||(LA12_1 >= '0' && LA12_1 <= '\uFFFF')) ) { + alt12=1; + } + + } + else if ( ((LA12_0 >= '\u0000' && LA12_0 <= ')')||(LA12_0 >= '+' && LA12_0 <= '\uFFFF')) ) { + alt12=1; + } + + switch (alt12) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:140:42: . + { + matchAny(); + } + break; + + default : + break loop12; + } + } + + match("*/"); + + _channel=HIDDEN; + } + break; + + } + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "COMMENT" + + // $ANTLR start "WS" + public final void mWS() throws RecognitionException { + try { + int _type = WS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:143:5: ( ( ' ' | '\\t' | '\\r' | '\\n' | '\\r\\n' ) ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:143:9: ( ' ' | '\\t' | '\\r' | '\\n' | '\\r\\n' ) + { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:143:9: ( ' ' | '\\t' | '\\r' | '\\n' | '\\r\\n' ) + int alt14=5; + switch ( input.LA(1) ) { + case ' ': + { + alt14=1; + } + break; + case '\t': + { + alt14=2; + } + break; + case '\r': + { + int LA14_3 = input.LA(2); + if ( (LA14_3=='\n') ) { + alt14=5; + } + + else { + alt14=3; + } + + } + break; + case '\n': + { + alt14=4; + } + break; + default: + NoViableAltException nvae = + new NoViableAltException("", 14, 0, input); + throw nvae; + } + switch (alt14) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:143:11: ' ' + { + match(' '); + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:144:11: '\\t' + { + match('\t'); + } + break; + case 3 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:145:11: '\\r' + { + match('\r'); + } + break; + case 4 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:146:11: '\\n' + { + match('\n'); + } + break; + case 5 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:147:10: '\\r\\n' + { + match("\r\n"); + + } + break; + + } + + _channel=HIDDEN; + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "WS" + + // $ANTLR start "STRING" + public final void mSTRING() throws RecognitionException { + try { + int _type = STRING; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:154:5: ( '\\'' ( ESC_SEQ |~ ( '\\\\' | '\\'' ) )* '\\'' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:154:8: '\\'' ( ESC_SEQ |~ ( '\\\\' | '\\'' ) )* '\\'' + { + match('\''); + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:154:13: ( ESC_SEQ |~ ( '\\\\' | '\\'' ) )* + loop15: + while (true) { + int alt15=3; + int LA15_0 = input.LA(1); + if ( (LA15_0=='\\') ) { + alt15=1; + } + else if ( ((LA15_0 >= '\u0000' && LA15_0 <= '&')||(LA15_0 >= '(' && LA15_0 <= '[')||(LA15_0 >= ']' && LA15_0 <= '\uFFFF')) ) { + alt15=2; + } + + switch (alt15) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:154:15: ESC_SEQ + { + mESC_SEQ(); + + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:154:25: ~ ( '\\\\' | '\\'' ) + { + if ( (input.LA(1) >= '\u0000' && input.LA(1) <= '&')||(input.LA(1) >= '(' && input.LA(1) <= '[')||(input.LA(1) >= ']' && input.LA(1) <= '\uFFFF') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + } + break; + + default : + break loop15; + } + } + + match('\''); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "STRING" + + // $ANTLR start "EXPONENT" + public final void mEXPONENT() throws RecognitionException { + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:160:10: ( ( 'e' | 'E' ) ( '+' | '-' )? ( '0' .. '9' )+ ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:160:12: ( 'e' | 'E' ) ( '+' | '-' )? ( '0' .. '9' )+ + { + if ( input.LA(1)=='E'||input.LA(1)=='e' ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:160:22: ( '+' | '-' )? + int alt16=2; + int LA16_0 = input.LA(1); + if ( (LA16_0=='+'||LA16_0=='-') ) { + alt16=1; + } + switch (alt16) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g: + { + if ( input.LA(1)=='+'||input.LA(1)=='-' ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + } + break; + + } + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:160:33: ( '0' .. '9' )+ + int cnt17=0; + loop17: + while (true) { + int alt17=2; + int LA17_0 = input.LA(1); + if ( ((LA17_0 >= '0' && LA17_0 <= '9')) ) { + alt17=1; + } + + switch (alt17) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g: + { + if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + } + break; + + default : + if ( cnt17 >= 1 ) break loop17; + EarlyExitException eee = new EarlyExitException(17, input); + throw eee; + } + cnt17++; + } + + } + + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "EXPONENT" + + // $ANTLR start "HEX_DIGIT" + public final void mHEX_DIGIT() throws RecognitionException { + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:163:11: ( ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' ) ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g: + { + if ( (input.LA(1) >= '0' && input.LA(1) <= '9')||(input.LA(1) >= 'A' && input.LA(1) <= 'F')||(input.LA(1) >= 'a' && input.LA(1) <= 'f') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + } + + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "HEX_DIGIT" + + // $ANTLR start "ESC_SEQ" + public final void mESC_SEQ() throws RecognitionException { + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:167:5: ( '\\\\' ( 'b' | 't' | 'n' | 'f' | 'r' | '\\\"' | '\\'' | '\\\\' ) | UNICODE_ESC | OCTAL_ESC ) + int alt18=3; + int LA18_0 = input.LA(1); + if ( (LA18_0=='\\') ) { + switch ( input.LA(2) ) { + case '\"': + case '\'': + case '\\': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': + { + alt18=1; + } + break; + case 'u': + { + alt18=2; + } + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + alt18=3; + } + break; + default: + int nvaeMark = input.mark(); + try { + input.consume(); + NoViableAltException nvae = + new NoViableAltException("", 18, 1, input); + throw nvae; + } finally { + input.rewind(nvaeMark); + } + } + } + + else { + NoViableAltException nvae = + new NoViableAltException("", 18, 0, input); + throw nvae; + } + + switch (alt18) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:167:9: '\\\\' ( 'b' | 't' | 'n' | 'f' | 'r' | '\\\"' | '\\'' | '\\\\' ) + { + match('\\'); + if ( input.LA(1)=='\"'||input.LA(1)=='\''||input.LA(1)=='\\'||input.LA(1)=='b'||input.LA(1)=='f'||input.LA(1)=='n'||input.LA(1)=='r'||input.LA(1)=='t' ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:168:9: UNICODE_ESC + { + mUNICODE_ESC(); + + } + break; + case 3 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:169:9: OCTAL_ESC + { + mOCTAL_ESC(); + + } + break; + + } + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "ESC_SEQ" + + // $ANTLR start "OCTAL_ESC" + public final void mOCTAL_ESC() throws RecognitionException { + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:174:5: ( '\\\\' ( '0' .. '3' ) ( '0' .. '7' ) ( '0' .. '7' ) | '\\\\' ( '0' .. '7' ) ( '0' .. '7' ) | '\\\\' ( '0' .. '7' ) ) + int alt19=3; + int LA19_0 = input.LA(1); + if ( (LA19_0=='\\') ) { + int LA19_1 = input.LA(2); + if ( ((LA19_1 >= '0' && LA19_1 <= '3')) ) { + int LA19_2 = input.LA(3); + if ( ((LA19_2 >= '0' && LA19_2 <= '7')) ) { + int LA19_4 = input.LA(4); + if ( ((LA19_4 >= '0' && LA19_4 <= '7')) ) { + alt19=1; + } + + else { + alt19=2; + } + + } + + else { + alt19=3; + } + + } + else if ( ((LA19_1 >= '4' && LA19_1 <= '7')) ) { + int LA19_3 = input.LA(3); + if ( ((LA19_3 >= '0' && LA19_3 <= '7')) ) { + alt19=2; + } + + else { + alt19=3; + } + + } + + else { + int nvaeMark = input.mark(); + try { + input.consume(); + NoViableAltException nvae = + new NoViableAltException("", 19, 1, input); + throw nvae; + } finally { + input.rewind(nvaeMark); + } + } + + } + + else { + NoViableAltException nvae = + new NoViableAltException("", 19, 0, input); + throw nvae; + } + + switch (alt19) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:174:9: '\\\\' ( '0' .. '3' ) ( '0' .. '7' ) ( '0' .. '7' ) + { + match('\\'); + if ( (input.LA(1) >= '0' && input.LA(1) <= '3') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + if ( (input.LA(1) >= '0' && input.LA(1) <= '7') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + if ( (input.LA(1) >= '0' && input.LA(1) <= '7') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:175:9: '\\\\' ( '0' .. '7' ) ( '0' .. '7' ) + { + match('\\'); + if ( (input.LA(1) >= '0' && input.LA(1) <= '7') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + if ( (input.LA(1) >= '0' && input.LA(1) <= '7') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + } + break; + case 3 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:176:9: '\\\\' ( '0' .. '7' ) + { + match('\\'); + if ( (input.LA(1) >= '0' && input.LA(1) <= '7') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + } + break; + + } + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "OCTAL_ESC" + + // $ANTLR start "UNICODE_ESC" + public final void mUNICODE_ESC() throws RecognitionException { + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:181:5: ( '\\\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:181:9: '\\\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT + { + match('\\'); + match('u'); + mHEX_DIGIT(); + + mHEX_DIGIT(); + + mHEX_DIGIT(); + + mHEX_DIGIT(); + + } + + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "UNICODE_ESC" + + // $ANTLR start "PLUS" + public final void mPLUS() throws RecognitionException { + try { + int _type = PLUS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:187:2: ( '+' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:187:2: '+' + { + match('+'); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "PLUS" + + // $ANTLR start "MINUS" + public final void mMINUS() throws RecognitionException { + try { + int _type = MINUS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:191:3: ( '-' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:191:3: '-' + { + match('-'); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "MINUS" + + // $ANTLR start "MULT" + public final void mMULT() throws RecognitionException { + try { + int _type = MULT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:196:2: ( '*' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:196:2: '*' + { + match('*'); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "MULT" + + // $ANTLR start "DIV" + public final void mDIV() throws RecognitionException { + try { + int _type = DIV; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:200:2: ( '/' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:200:2: '/' + { + match('/'); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "DIV" + + // $ANTLR start "DASH" + public final void mDASH() throws RecognitionException { + try { + int _type = DASH; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:204:2: ( '***' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:204:2: '***' + { + match("***"); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "DASH" + + // $ANTLR start "EQUAL" + public final void mEQUAL() throws RecognitionException { + try { + int _type = EQUAL; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:207:2: ( '=' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:207:2: '=' + { + match('='); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "EQUAL" + + // $ANTLR start "NOT_EQUAL" + public final void mNOT_EQUAL() throws RecognitionException { + try { + int _type = NOT_EQUAL; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:212:2: ( '!=' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:212:2: '!=' + { + match("!="); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "NOT_EQUAL" + + // $ANTLR start "GET" + public final void mGET() throws RecognitionException { + try { + int _type = GET; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:216:2: ( '>' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:216:2: '>' + { + match('>'); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "GET" + + // $ANTLR start "LET" + public final void mLET() throws RecognitionException { + try { + int _type = LET; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:220:2: ( '<' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:220:2: '<' + { + match('<'); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "LET" + + // $ANTLR start "GETEQ" + public final void mGETEQ() throws RecognitionException { + try { + int _type = GETEQ; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:224:2: ( '>=' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:224:2: '>=' + { + match(">="); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "GETEQ" + + // $ANTLR start "LETEQ" + public final void mLETEQ() throws RecognitionException { + try { + int _type = LETEQ; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:227:2: ( '<=' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:227:2: '<=' + { + match("<="); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "LETEQ" + + // $ANTLR start "SAMEAS" + public final void mSAMEAS() throws RecognitionException { + try { + int _type = SAMEAS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:232:2: ( '==' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:232:2: '==' + { + match("=="); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "SAMEAS" + + // $ANTLR start "LPARA" + public final void mLPARA() throws RecognitionException { + try { + int _type = LPARA; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:238:2: ( '(' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:238:2: '(' + { + match('('); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "LPARA" + + // $ANTLR start "RPARA" + public final void mRPARA() throws RecognitionException { + try { + int _type = RPARA; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:242:2: ( ')' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:242:2: ')' + { + match(')'); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "RPARA" + + // $ANTLR start "LCURL" + public final void mLCURL() throws RecognitionException { + try { + int _type = LCURL; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:246:2: ( '{' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:246:2: '{' + { + match('{'); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "LCURL" + + // $ANTLR start "RCURL" + public final void mRCURL() throws RecognitionException { + try { + int _type = RCURL; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:250:2: ( '}' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:250:2: '}' + { + match('}'); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "RCURL" + + // $ANTLR start "SEMICOL" + public final void mSEMICOL() throws RecognitionException { + try { + int _type = SEMICOL; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:256:2: ( ';' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:256:2: ';' + { + match(';'); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "SEMICOL" + + // $ANTLR start "COMMA" + public final void mCOMMA() throws RecognitionException { + try { + int _type = COMMA; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:260:2: ( ',' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:260:2: ',' + { + match(','); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "COMMA" + + // $ANTLR start "UNIFORM" + public final void mUNIFORM() throws RecognitionException { + try { + int _type = UNIFORM; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:263:2: ( 'uniform(' INT ',' INT ')' ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:263:2: 'uniform(' INT ',' INT ')' + { + match("uniform("); + + mINT(); + + match(','); + mINT(); + + match(')'); + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "UNIFORM" + + @Override + public void mTokens() throws RecognitionException { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:8: ( T__54 | SENALWAYS | ALWAYS | BOOLEAN | REAL | INTEGER | WAIT | WAIT_DELAY | NOT | MOD | AND | OR | ASSERT | IF | END | ELSEIF | ELSE | WAIT_STABLE | ASSERT_STABLE | ASSERT_UNTIL | WAIT_POSEDGE | ID | INT | FLOAT | COMMENT | WS | STRING | PLUS | MINUS | MULT | DIV | DASH | EQUAL | NOT_EQUAL | GET | LET | GETEQ | LETEQ | SAMEAS | LPARA | RPARA | LCURL | RCURL | SEMICOL | COMMA | UNIFORM ) + int alt20=46; + alt20 = dfa20.predict(input); + switch (alt20) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:10: T__54 + { + mT__54(); + + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:16: SENALWAYS + { + mSENALWAYS(); + + } + break; + case 3 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:26: ALWAYS + { + mALWAYS(); + + } + break; + case 4 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:33: BOOLEAN + { + mBOOLEAN(); + + } + break; + case 5 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:41: REAL + { + mREAL(); + + } + break; + case 6 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:46: INTEGER + { + mINTEGER(); + + } + break; + case 7 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:54: WAIT + { + mWAIT(); + + } + break; + case 8 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:59: WAIT_DELAY + { + mWAIT_DELAY(); + + } + break; + case 9 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:70: NOT + { + mNOT(); + + } + break; + case 10 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:74: MOD + { + mMOD(); + + } + break; + case 11 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:78: AND + { + mAND(); + + } + break; + case 12 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:82: OR + { + mOR(); + + } + break; + case 13 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:85: ASSERT + { + mASSERT(); + + } + break; + case 14 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:92: IF + { + mIF(); + + } + break; + case 15 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:95: END + { + mEND(); + + } + break; + case 16 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:99: ELSEIF + { + mELSEIF(); + + } + break; + case 17 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:106: ELSE + { + mELSE(); + + } + break; + case 18 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:111: WAIT_STABLE + { + mWAIT_STABLE(); + + } + break; + case 19 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:123: ASSERT_STABLE + { + mASSERT_STABLE(); + + } + break; + case 20 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:137: ASSERT_UNTIL + { + mASSERT_UNTIL(); + + } + break; + case 21 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:150: WAIT_POSEDGE + { + mWAIT_POSEDGE(); + + } + break; + case 22 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:163: ID + { + mID(); + + } + break; + case 23 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:166: INT + { + mINT(); + + } + break; + case 24 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:170: FLOAT + { + mFLOAT(); + + } + break; + case 25 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:176: COMMENT + { + mCOMMENT(); + + } + break; + case 26 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:184: WS + { + mWS(); + + } + break; + case 27 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:187: STRING + { + mSTRING(); + + } + break; + case 28 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:194: PLUS + { + mPLUS(); + + } + break; + case 29 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:199: MINUS + { + mMINUS(); + + } + break; + case 30 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:205: MULT + { + mMULT(); + + } + break; + case 31 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:210: DIV + { + mDIV(); + + } + break; + case 32 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:214: DASH + { + mDASH(); + + } + break; + case 33 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:219: EQUAL + { + mEQUAL(); + + } + break; + case 34 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:225: NOT_EQUAL + { + mNOT_EQUAL(); + + } + break; + case 35 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:235: GET + { + mGET(); + + } + break; + case 36 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:239: LET + { + mLET(); + + } + break; + case 37 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:243: GETEQ + { + mGETEQ(); + + } + break; + case 38 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:249: LETEQ + { + mLETEQ(); + + } + break; + case 39 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:255: SAMEAS + { + mSAMEAS(); + + } + break; + case 40 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:262: LPARA + { + mLPARA(); + + } + break; + case 41 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:268: RPARA + { + mRPARA(); + + } + break; + case 42 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:274: LCURL + { + mLCURL(); + + } + break; + case 43 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:280: RCURL + { + mRCURL(); + + } + break; + case 44 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:286: SEMICOL + { + mSEMICOL(); + + } + break; + case 45 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:294: COMMA + { + mCOMMA(); + + } + break; + case 46 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:1:300: UNIFORM + { + mUNIFORM(); + + } + break; + + } + } + + + protected DFA9 dfa9 = new DFA9(this); + protected DFA20 dfa20 = new DFA20(this); + static final String DFA9_eotS = + "\5\uffff"; + static final String DFA9_eofS = + "\5\uffff"; + static final String DFA9_minS = + "\2\56\3\uffff"; + static final String DFA9_maxS = + "\1\71\1\145\3\uffff"; + static final String DFA9_acceptS = + "\2\uffff\1\2\1\1\1\3"; + static final String DFA9_specialS = + "\5\uffff}>"; + static final String[] DFA9_transitionS = { + "\1\2\1\uffff\12\1", + "\1\3\1\uffff\12\1\13\uffff\1\4\37\uffff\1\4", + "", + "", + "" + }; + + static final short[] DFA9_eot = DFA.unpackEncodedString(DFA9_eotS); + static final short[] DFA9_eof = DFA.unpackEncodedString(DFA9_eofS); + static final char[] DFA9_min = DFA.unpackEncodedStringToUnsignedChars(DFA9_minS); + static final char[] DFA9_max = DFA.unpackEncodedStringToUnsignedChars(DFA9_maxS); + static final short[] DFA9_accept = DFA.unpackEncodedString(DFA9_acceptS); + static final short[] DFA9_special = DFA.unpackEncodedString(DFA9_specialS); + static final short[][] DFA9_transition; + + static { + int numStates = DFA9_transitionS.length; + DFA9_transition = new short[numStates][]; + for (int i=0; i"; + static final String[] DFA20_transitionS = { + "\2\21\2\uffff\1\21\22\uffff\1\21\1\27\3\uffff\1\11\1\12\1\22\1\32\1\33"+ + "\1\25\1\23\1\37\1\24\1\17\1\20\12\16\1\uffff\1\36\1\31\1\26\1\30\2\uffff"+ + "\32\40\4\uffff\1\40\1\uffff\1\3\1\4\2\40\1\14\3\40\1\6\6\40\1\1\1\40"+ + "\1\5\1\2\1\40\1\15\1\40\1\7\3\40\1\34\1\13\1\35\1\10", + "\1\41", + "\1\42", + "\1\43\6\uffff\1\44", + "\1\45", + "\1\46", + "\1\50\7\uffff\1\47", + "\1\51", + "", + "", + "", + "", + "\1\53\1\uffff\1\52", + "\1\54", + "\1\17\1\uffff\12\16\13\uffff\1\17\37\uffff\1\17", + "", + "\1\56\4\uffff\1\56", + "", + "", + "", + "", + "\1\60", + "\1\62", + "", + "\1\64", + "\1\66", + "", + "", + "", + "", + "", + "", + "", + "\1\70", + "\1\71", + "\1\72", + "\1\73", + "\1\74", + "\1\75", + "\1\76", + "\12\40\7\uffff\32\40\4\uffff\1\40\1\uffff\32\40", + "\1\100", + "\1\101", + "\1\102", + "\1\103", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "\1\104", + "\1\105", + "\1\106", + "\1\107", + "\1\110", + "\1\111", + "\12\40\7\uffff\32\40\4\uffff\1\40\1\uffff\32\40", + "", + "\1\113", + "\12\40\7\uffff\32\40\4\uffff\1\40\1\uffff\32\40", + "\1\115", + "\1\116", + "\1\117", + "\1\120", + "\1\121", + "\1\122", + "\1\123", + "\12\40\7\uffff\32\40\4\uffff\1\40\1\uffff\32\40", + "", + "\12\40\7\uffff\3\40\1\125\13\40\1\127\2\40\1\126\7\40\4\uffff\1\40\1"+ + "\uffff\32\40", + "", + "\1\131\17\uffff\12\40\7\uffff\32\40\4\uffff\1\40\1\uffff\32\40", + "\1\133", + "\1\134", + "\1\135", + "\1\136", + "\1\137", + "\1\140", + "", + "\1\141", + "\1\142", + "\1\143", + "", + "", + "", + "\1\144", + "\1\145", + "\1\146", + "\12\40\7\uffff\32\40\4\uffff\1\40\1\uffff\32\40", + "\12\40\7\uffff\22\40\1\150\1\40\1\151\5\40\4\uffff\1\40\1\uffff\32\40", + "\1\153", + "\1\154", + "\1\155", + "\1\156", + "\1\157", + "\1\160", + "\1\161", + "", + "\1\162", + "\1\163", + "", + "\12\40\7\uffff\32\40\4\uffff\1\40\1\uffff\32\40", + "\1\165", + "\1\166", + "\1\167", + "\1\170", + "\12\40\7\uffff\32\40\4\uffff\1\40\1\uffff\32\40", + "\1\172", + "\1\173", + "\1\174", + "", + "\1\175", + "\1\176", + "\1\177", + "", + "", + "\12\40\7\uffff\32\40\4\uffff\1\40\1\uffff\32\40", + "\1\u0081", + "\1\u0082", + "\12\40\7\uffff\32\40\4\uffff\1\40\1\uffff\32\40", + "\1\u0084", + "\1\u0085", + "", + "\1\u0086", + "\1\u0087", + "", + "\12\40\7\uffff\32\40\4\uffff\1\40\1\uffff\32\40", + "\1\u0089", + "\1\u008a", + "\12\40\7\uffff\32\40\4\uffff\1\40\1\uffff\32\40", + "", + "\12\40\7\uffff\32\40\4\uffff\1\40\1\uffff\32\40", + "\12\40\7\uffff\32\40\4\uffff\1\40\1\uffff\32\40", + "", + "", + "" + }; + + static final short[] DFA20_eot = DFA.unpackEncodedString(DFA20_eotS); + static final short[] DFA20_eof = DFA.unpackEncodedString(DFA20_eofS); + static final char[] DFA20_min = DFA.unpackEncodedStringToUnsignedChars(DFA20_minS); + static final char[] DFA20_max = DFA.unpackEncodedStringToUnsignedChars(DFA20_maxS); + static final short[] DFA20_accept = DFA.unpackEncodedString(DFA20_acceptS); + static final short[] DFA20_special = DFA.unpackEncodedString(DFA20_specialS); + static final short[][] DFA20_transition; + + static { + int numStates = DFA20_transitionS.length; + DFA20_transition = new short[numStates][]; + for (int i=0; i + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +// $ANTLR 3.5 /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g 2016-09-01 11:02:46 + +package edu.utah.ece.async.lema.verification.lpn.properties; + +import org.antlr.runtime.*; +import java.util.Stack; +import java.util.List; +import java.util.ArrayList; + +import org.antlr.runtime.tree.*; + + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +@SuppressWarnings("all") +public class PropertyParser extends Parser { + public static final String[] tokenNames = new String[] { + "", "", "", "", "ALWAYS", "AND", "ASSERT", "ASSERT_STABLE", + "ASSERT_UNTIL", "BOOLEAN", "COMMA", "COMMENT", "DASH", "DIV", "ELSE", + "ELSEIF", "END", "EQUAL", "ESC_SEQ", "EXPONENT", "FLOAT", "GET", "GETEQ", + "HEX_DIGIT", "ID", "IF", "INT", "INTEGER", "LCURL", "LET", "LETEQ", "LPARA", + "MINUS", "MOD", "MULT", "NOT", "NOT_EQUAL", "OCTAL_ESC", "OR", "PLUS", + "RCURL", "REAL", "RPARA", "SAMEAS", "SEMICOL", "SENALWAYS", "STRING", + "UNICODE_ESC", "UNIFORM", "WAIT", "WAIT_DELAY", "WAIT_POSEDGE", "WAIT_STABLE", + "WS", "'property'" + }; + public static final int EOF=-1; + public static final int T__54=54; + public static final int ALWAYS=4; + public static final int AND=5; + public static final int ASSERT=6; + public static final int ASSERT_STABLE=7; + public static final int ASSERT_UNTIL=8; + public static final int BOOLEAN=9; + public static final int COMMA=10; + public static final int COMMENT=11; + public static final int DASH=12; + public static final int DIV=13; + public static final int ELSE=14; + public static final int ELSEIF=15; + public static final int END=16; + public static final int EQUAL=17; + public static final int ESC_SEQ=18; + public static final int EXPONENT=19; + public static final int FLOAT=20; + public static final int GET=21; + public static final int GETEQ=22; + public static final int HEX_DIGIT=23; + public static final int ID=24; + public static final int IF=25; + public static final int INT=26; + public static final int INTEGER=27; + public static final int LCURL=28; + public static final int LET=29; + public static final int LETEQ=30; + public static final int LPARA=31; + public static final int MINUS=32; + public static final int MOD=33; + public static final int MULT=34; + public static final int NOT=35; + public static final int NOT_EQUAL=36; + public static final int OCTAL_ESC=37; + public static final int OR=38; + public static final int PLUS=39; + public static final int RCURL=40; + public static final int REAL=41; + public static final int RPARA=42; + public static final int SAMEAS=43; + public static final int SEMICOL=44; + public static final int SENALWAYS=45; + public static final int STRING=46; + public static final int UNICODE_ESC=47; + public static final int UNIFORM=48; + public static final int WAIT=49; + public static final int WAIT_DELAY=50; + public static final int WAIT_POSEDGE=51; + public static final int WAIT_STABLE=52; + public static final int WS=53; + + // delegates + public Parser[] getDelegates() { + return new Parser[] {}; + } + + // delegators + + + public PropertyParser(TokenStream input) { + this(input, new RecognizerSharedState()); + } + public PropertyParser(TokenStream input, RecognizerSharedState state) { + super(input, state); + } + + protected TreeAdaptor adaptor = new CommonTreeAdaptor(); + + public void setTreeAdaptor(TreeAdaptor adaptor) { + this.adaptor = adaptor; + } + public TreeAdaptor getTreeAdaptor() { + return adaptor; + } + @Override public String[] getTokenNames() { return PropertyParser.tokenNames; } + @Override public String getGrammarFileName() { return "/Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g"; } + + + public static class program_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "program" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:24:1: program : property ; + public final PropertyParser.program_return program() throws Exception { + PropertyParser.program_return retval = new PropertyParser.program_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + ParserRuleReturnScope property1 =null; + + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:25:2: ( property ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:25:3: property + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_property_in_program61); + property1=property(); + state._fsp--; + + adaptor.addChild(root_0, property1.getTree()); + + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "program" + + + public static class property_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "property" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:28:1: property : 'property' ^ ID LCURL ! ( declaration )* ( statement )* RCURL !; + public final PropertyParser.property_return property() throws Exception { + PropertyParser.property_return retval = new PropertyParser.property_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token string_literal2=null; + Token ID3=null; + Token LCURL4=null; + Token RCURL7=null; + ParserRuleReturnScope declaration5 =null; + ParserRuleReturnScope statement6 =null; + + CommonTree string_literal2_tree=null; + CommonTree ID3_tree=null; + CommonTree LCURL4_tree=null; + CommonTree RCURL7_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:29:3: ( 'property' ^ ID LCURL ! ( declaration )* ( statement )* RCURL !) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:29:3: 'property' ^ ID LCURL ! ( declaration )* ( statement )* RCURL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + string_literal2=(Token)match(input,54,FOLLOW_54_in_property72); + string_literal2_tree = (CommonTree)adaptor.create(string_literal2); + root_0 = (CommonTree)adaptor.becomeRoot(string_literal2_tree, root_0); + + ID3=(Token)match(input,ID,FOLLOW_ID_in_property75); + ID3_tree = (CommonTree)adaptor.create(ID3); + adaptor.addChild(root_0, ID3_tree); + + LCURL4=(Token)match(input,LCURL,FOLLOW_LCURL_in_property77); + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:29:25: ( declaration )* + loop1: + while (true) { + int alt1=2; + int LA1_0 = input.LA(1); + if ( (LA1_0==BOOLEAN||LA1_0==INTEGER||LA1_0==REAL) ) { + alt1=1; + } + + switch (alt1) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:29:26: declaration + { + pushFollow(FOLLOW_declaration_in_property81); + declaration5=declaration(); + state._fsp--; + + adaptor.addChild(root_0, declaration5.getTree()); + + } + break; + + default : + break loop1; + } + } + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:29:40: ( statement )* + loop2: + while (true) { + int alt2=2; + int LA2_0 = input.LA(1); + if ( (LA2_0==ALWAYS||(LA2_0 >= ASSERT && LA2_0 <= ASSERT_UNTIL)||LA2_0==IF||LA2_0==SENALWAYS||(LA2_0 >= WAIT && LA2_0 <= WAIT_STABLE)) ) { + alt2=1; + } + + switch (alt2) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:29:41: statement + { + pushFollow(FOLLOW_statement_in_property86); + statement6=statement(); + state._fsp--; + + adaptor.addChild(root_0, statement6.getTree()); + + } + break; + + default : + break loop2; + } + } + + RCURL7=(Token)match(input,RCURL,FOLLOW_RCURL_in_property90); + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "property" + + + public static class declaration_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "declaration" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:32:1: declaration : ( BOOLEAN ^ ID ( COMMA ! ID )* SEMICOL !| REAL ^ ID ( COMMA ! ID )* SEMICOL !| INTEGER ^ ID ( COMMA ! ID )* SEMICOL !); + public final PropertyParser.declaration_return declaration() throws Exception { + PropertyParser.declaration_return retval = new PropertyParser.declaration_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token BOOLEAN8=null; + Token ID9=null; + Token COMMA10=null; + Token ID11=null; + Token SEMICOL12=null; + Token REAL13=null; + Token ID14=null; + Token COMMA15=null; + Token ID16=null; + Token SEMICOL17=null; + Token INTEGER18=null; + Token ID19=null; + Token COMMA20=null; + Token ID21=null; + Token SEMICOL22=null; + + CommonTree BOOLEAN8_tree=null; + CommonTree ID9_tree=null; + CommonTree COMMA10_tree=null; + CommonTree ID11_tree=null; + CommonTree SEMICOL12_tree=null; + CommonTree REAL13_tree=null; + CommonTree ID14_tree=null; + CommonTree COMMA15_tree=null; + CommonTree ID16_tree=null; + CommonTree SEMICOL17_tree=null; + CommonTree INTEGER18_tree=null; + CommonTree ID19_tree=null; + CommonTree COMMA20_tree=null; + CommonTree ID21_tree=null; + CommonTree SEMICOL22_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:33:3: ( BOOLEAN ^ ID ( COMMA ! ID )* SEMICOL !| REAL ^ ID ( COMMA ! ID )* SEMICOL !| INTEGER ^ ID ( COMMA ! ID )* SEMICOL !) + int alt6=3; + switch ( input.LA(1) ) { + case BOOLEAN: + { + alt6=1; + } + break; + case REAL: + { + alt6=2; + } + break; + case INTEGER: + { + alt6=3; + } + break; + default: + NoViableAltException nvae = + new NoViableAltException("", 6, 0, input); + throw nvae; + } + switch (alt6) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:33:4: BOOLEAN ^ ID ( COMMA ! ID )* SEMICOL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + BOOLEAN8=(Token)match(input,BOOLEAN,FOLLOW_BOOLEAN_in_declaration102); + BOOLEAN8_tree = (CommonTree)adaptor.create(BOOLEAN8); + root_0 = (CommonTree)adaptor.becomeRoot(BOOLEAN8_tree, root_0); + + ID9=(Token)match(input,ID,FOLLOW_ID_in_declaration105); + ID9_tree = (CommonTree)adaptor.create(ID9); + adaptor.addChild(root_0, ID9_tree); + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:33:16: ( COMMA ! ID )* + loop3: + while (true) { + int alt3=2; + int LA3_0 = input.LA(1); + if ( (LA3_0==COMMA) ) { + alt3=1; + } + + switch (alt3) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:33:17: COMMA ! ID + { + COMMA10=(Token)match(input,COMMA,FOLLOW_COMMA_in_declaration108); + ID11=(Token)match(input,ID,FOLLOW_ID_in_declaration111); + ID11_tree = (CommonTree)adaptor.create(ID11); + adaptor.addChild(root_0, ID11_tree); + + } + break; + + default : + break loop3; + } + } + + SEMICOL12=(Token)match(input,SEMICOL,FOLLOW_SEMICOL_in_declaration115); + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:34:5: REAL ^ ID ( COMMA ! ID )* SEMICOL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + REAL13=(Token)match(input,REAL,FOLLOW_REAL_in_declaration122); + REAL13_tree = (CommonTree)adaptor.create(REAL13); + root_0 = (CommonTree)adaptor.becomeRoot(REAL13_tree, root_0); + + ID14=(Token)match(input,ID,FOLLOW_ID_in_declaration125); + ID14_tree = (CommonTree)adaptor.create(ID14); + adaptor.addChild(root_0, ID14_tree); + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:34:14: ( COMMA ! ID )* + loop4: + while (true) { + int alt4=2; + int LA4_0 = input.LA(1); + if ( (LA4_0==COMMA) ) { + alt4=1; + } + + switch (alt4) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:34:15: COMMA ! ID + { + COMMA15=(Token)match(input,COMMA,FOLLOW_COMMA_in_declaration128); + ID16=(Token)match(input,ID,FOLLOW_ID_in_declaration131); + ID16_tree = (CommonTree)adaptor.create(ID16); + adaptor.addChild(root_0, ID16_tree); + + } + break; + + default : + break loop4; + } + } + + SEMICOL17=(Token)match(input,SEMICOL,FOLLOW_SEMICOL_in_declaration135); + } + break; + case 3 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:35:5: INTEGER ^ ID ( COMMA ! ID )* SEMICOL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + INTEGER18=(Token)match(input,INTEGER,FOLLOW_INTEGER_in_declaration142); + INTEGER18_tree = (CommonTree)adaptor.create(INTEGER18); + root_0 = (CommonTree)adaptor.becomeRoot(INTEGER18_tree, root_0); + + ID19=(Token)match(input,ID,FOLLOW_ID_in_declaration145); + ID19_tree = (CommonTree)adaptor.create(ID19); + adaptor.addChild(root_0, ID19_tree); + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:35:17: ( COMMA ! ID )* + loop5: + while (true) { + int alt5=2; + int LA5_0 = input.LA(1); + if ( (LA5_0==COMMA) ) { + alt5=1; + } + + switch (alt5) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:35:18: COMMA ! ID + { + COMMA20=(Token)match(input,COMMA,FOLLOW_COMMA_in_declaration148); + ID21=(Token)match(input,ID,FOLLOW_ID_in_declaration151); + ID21_tree = (CommonTree)adaptor.create(ID21); + adaptor.addChild(root_0, ID21_tree); + + } + break; + + default : + break loop5; + } + } + + SEMICOL22=(Token)match(input,SEMICOL,FOLLOW_SEMICOL_in_declaration155); + } + break; + + } + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "declaration" + + + public static class booleanNegationExpression_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "booleanNegationExpression" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:266:1: booleanNegationExpression : ( NOT ^)* constantValue ; + public final PropertyParser.booleanNegationExpression_return booleanNegationExpression() throws Exception { + PropertyParser.booleanNegationExpression_return retval = new PropertyParser.booleanNegationExpression_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token NOT23=null; + ParserRuleReturnScope constantValue24 =null; + + CommonTree NOT23_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:267:3: ( ( NOT ^)* constantValue ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:267:3: ( NOT ^)* constantValue + { + root_0 = (CommonTree)adaptor.nil(); + + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:267:3: ( NOT ^)* + loop7: + while (true) { + int alt7=2; + int LA7_0 = input.LA(1); + if ( (LA7_0==NOT) ) { + alt7=1; + } + + switch (alt7) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:267:4: NOT ^ + { + NOT23=(Token)match(input,NOT,FOLLOW_NOT_in_booleanNegationExpression1052); + NOT23_tree = (CommonTree)adaptor.create(NOT23); + root_0 = (CommonTree)adaptor.becomeRoot(NOT23_tree, root_0); + + } + break; + + default : + break loop7; + } + } + + pushFollow(FOLLOW_constantValue_in_booleanNegationExpression1057); + constantValue24=constantValue(); + state._fsp--; + + adaptor.addChild(root_0, constantValue24.getTree()); + + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "booleanNegationExpression" + + + public static class always_statement_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "always_statement" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:271:1: always_statement : ALWAYS ^ LCURL ! ( statement )* RCURL !; + public final PropertyParser.always_statement_return always_statement() throws Exception { + PropertyParser.always_statement_return retval = new PropertyParser.always_statement_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token ALWAYS25=null; + Token LCURL26=null; + Token RCURL28=null; + ParserRuleReturnScope statement27 =null; + + CommonTree ALWAYS25_tree=null; + CommonTree LCURL26_tree=null; + CommonTree RCURL28_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:272:3: ( ALWAYS ^ LCURL ! ( statement )* RCURL !) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:272:5: ALWAYS ^ LCURL ! ( statement )* RCURL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + ALWAYS25=(Token)match(input,ALWAYS,FOLLOW_ALWAYS_in_always_statement1071); + ALWAYS25_tree = (CommonTree)adaptor.create(ALWAYS25); + root_0 = (CommonTree)adaptor.becomeRoot(ALWAYS25_tree, root_0); + + LCURL26=(Token)match(input,LCURL,FOLLOW_LCURL_in_always_statement1074); + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:272:20: ( statement )* + loop8: + while (true) { + int alt8=2; + int LA8_0 = input.LA(1); + if ( (LA8_0==ALWAYS||(LA8_0 >= ASSERT && LA8_0 <= ASSERT_UNTIL)||LA8_0==IF||LA8_0==SENALWAYS||(LA8_0 >= WAIT && LA8_0 <= WAIT_STABLE)) ) { + alt8=1; + } + + switch (alt8) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:272:21: statement + { + pushFollow(FOLLOW_statement_in_always_statement1078); + statement27=statement(); + state._fsp--; + + adaptor.addChild(root_0, statement27.getTree()); + + } + break; + + default : + break loop8; + } + } + + RCURL28=(Token)match(input,RCURL,FOLLOW_RCURL_in_always_statement1082); + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "always_statement" + + + public static class senalways_statement_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "senalways_statement" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:275:1: senalways_statement : SENALWAYS ^ ( sensitivityList )? LCURL ! ( statement )* RCURL !; + public final PropertyParser.senalways_statement_return senalways_statement() throws Exception { + PropertyParser.senalways_statement_return retval = new PropertyParser.senalways_statement_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token SENALWAYS29=null; + Token LCURL31=null; + Token RCURL33=null; + ParserRuleReturnScope sensitivityList30 =null; + ParserRuleReturnScope statement32 =null; + + CommonTree SENALWAYS29_tree=null; + CommonTree LCURL31_tree=null; + CommonTree RCURL33_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:276:3: ( SENALWAYS ^ ( sensitivityList )? LCURL ! ( statement )* RCURL !) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:276:5: SENALWAYS ^ ( sensitivityList )? LCURL ! ( statement )* RCURL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + SENALWAYS29=(Token)match(input,SENALWAYS,FOLLOW_SENALWAYS_in_senalways_statement1098); + SENALWAYS29_tree = (CommonTree)adaptor.create(SENALWAYS29); + root_0 = (CommonTree)adaptor.becomeRoot(SENALWAYS29_tree, root_0); + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:276:16: ( sensitivityList )? + int alt9=2; + int LA9_0 = input.LA(1); + if ( (LA9_0==LPARA) ) { + alt9=1; + } + switch (alt9) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:276:17: sensitivityList + { + pushFollow(FOLLOW_sensitivityList_in_senalways_statement1102); + sensitivityList30=sensitivityList(); + state._fsp--; + + adaptor.addChild(root_0, sensitivityList30.getTree()); + + } + break; + + } + + LCURL31=(Token)match(input,LCURL,FOLLOW_LCURL_in_senalways_statement1106); + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:276:42: ( statement )* + loop10: + while (true) { + int alt10=2; + int LA10_0 = input.LA(1); + if ( (LA10_0==ALWAYS||(LA10_0 >= ASSERT && LA10_0 <= ASSERT_UNTIL)||LA10_0==IF||LA10_0==SENALWAYS||(LA10_0 >= WAIT && LA10_0 <= WAIT_STABLE)) ) { + alt10=1; + } + + switch (alt10) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:276:43: statement + { + pushFollow(FOLLOW_statement_in_senalways_statement1110); + statement32=statement(); + state._fsp--; + + adaptor.addChild(root_0, statement32.getTree()); + + } + break; + + default : + break loop10; + } + } + + RCURL33=(Token)match(input,RCURL,FOLLOW_RCURL_in_senalways_statement1114); + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "senalways_statement" + + + public static class sensitivityList_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "sensitivityList" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:279:1: sensitivityList : ( LPARA ^ ID ( COMMA ! ID )* RPARA !) ; + public final PropertyParser.sensitivityList_return sensitivityList() throws Exception { + PropertyParser.sensitivityList_return retval = new PropertyParser.sensitivityList_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token LPARA34=null; + Token ID35=null; + Token COMMA36=null; + Token ID37=null; + Token RPARA38=null; + + CommonTree LPARA34_tree=null; + CommonTree ID35_tree=null; + CommonTree COMMA36_tree=null; + CommonTree ID37_tree=null; + CommonTree RPARA38_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:280:3: ( ( LPARA ^ ID ( COMMA ! ID )* RPARA !) ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:280:5: ( LPARA ^ ID ( COMMA ! ID )* RPARA !) + { + root_0 = (CommonTree)adaptor.nil(); + + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:280:5: ( LPARA ^ ID ( COMMA ! ID )* RPARA !) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:280:6: LPARA ^ ID ( COMMA ! ID )* RPARA ! + { + LPARA34=(Token)match(input,LPARA,FOLLOW_LPARA_in_sensitivityList1129); + LPARA34_tree = (CommonTree)adaptor.create(LPARA34); + root_0 = (CommonTree)adaptor.becomeRoot(LPARA34_tree, root_0); + + ID35=(Token)match(input,ID,FOLLOW_ID_in_sensitivityList1132); + ID35_tree = (CommonTree)adaptor.create(ID35); + adaptor.addChild(root_0, ID35_tree); + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:280:16: ( COMMA ! ID )* + loop11: + while (true) { + int alt11=2; + int LA11_0 = input.LA(1); + if ( (LA11_0==COMMA) ) { + alt11=1; + } + + switch (alt11) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:280:17: COMMA ! ID + { + COMMA36=(Token)match(input,COMMA,FOLLOW_COMMA_in_sensitivityList1135); + ID37=(Token)match(input,ID,FOLLOW_ID_in_sensitivityList1138); + ID37_tree = (CommonTree)adaptor.create(ID37); + adaptor.addChild(root_0, ID37_tree); + + } + break; + + default : + break loop11; + } + } + + RPARA38=(Token)match(input,RPARA,FOLLOW_RPARA_in_sensitivityList1142); + } + + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "sensitivityList" + + + public static class signExpression_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "signExpression" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:283:1: signExpression : ( PLUS ^| MINUS ^)* booleanNegationExpression ; + public final PropertyParser.signExpression_return signExpression() throws Exception { + PropertyParser.signExpression_return retval = new PropertyParser.signExpression_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token PLUS39=null; + Token MINUS40=null; + ParserRuleReturnScope booleanNegationExpression41 =null; + + CommonTree PLUS39_tree=null; + CommonTree MINUS40_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:284:2: ( ( PLUS ^| MINUS ^)* booleanNegationExpression ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:284:2: ( PLUS ^| MINUS ^)* booleanNegationExpression + { + root_0 = (CommonTree)adaptor.nil(); + + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:284:2: ( PLUS ^| MINUS ^)* + loop12: + while (true) { + int alt12=3; + int LA12_0 = input.LA(1); + if ( (LA12_0==PLUS) ) { + alt12=1; + } + else if ( (LA12_0==MINUS) ) { + alt12=2; + } + + switch (alt12) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:284:3: PLUS ^ + { + PLUS39=(Token)match(input,PLUS,FOLLOW_PLUS_in_signExpression1155); + PLUS39_tree = (CommonTree)adaptor.create(PLUS39); + root_0 = (CommonTree)adaptor.becomeRoot(PLUS39_tree, root_0); + + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:284:9: MINUS ^ + { + MINUS40=(Token)match(input,MINUS,FOLLOW_MINUS_in_signExpression1158); + MINUS40_tree = (CommonTree)adaptor.create(MINUS40); + root_0 = (CommonTree)adaptor.becomeRoot(MINUS40_tree, root_0); + + } + break; + + default : + break loop12; + } + } + + pushFollow(FOLLOW_booleanNegationExpression_in_signExpression1164); + booleanNegationExpression41=booleanNegationExpression(); + state._fsp--; + + adaptor.addChild(root_0, booleanNegationExpression41.getTree()); + + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "signExpression" + + + public static class multiplyingExpression_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "multiplyingExpression" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:287:1: multiplyingExpression : signExpression ( ( MULT ^| DIV ^| MOD ^) signExpression )* ; + public final PropertyParser.multiplyingExpression_return multiplyingExpression() throws Exception { + PropertyParser.multiplyingExpression_return retval = new PropertyParser.multiplyingExpression_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token MULT43=null; + Token DIV44=null; + Token MOD45=null; + ParserRuleReturnScope signExpression42 =null; + ParserRuleReturnScope signExpression46 =null; + + CommonTree MULT43_tree=null; + CommonTree DIV44_tree=null; + CommonTree MOD45_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:288:3: ( signExpression ( ( MULT ^| DIV ^| MOD ^) signExpression )* ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:288:5: signExpression ( ( MULT ^| DIV ^| MOD ^) signExpression )* + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_signExpression_in_multiplyingExpression1175); + signExpression42=signExpression(); + state._fsp--; + + adaptor.addChild(root_0, signExpression42.getTree()); + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:288:20: ( ( MULT ^| DIV ^| MOD ^) signExpression )* + loop14: + while (true) { + int alt14=2; + int LA14_0 = input.LA(1); + if ( (LA14_0==DIV||(LA14_0 >= MOD && LA14_0 <= MULT)) ) { + alt14=1; + } + + switch (alt14) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:288:21: ( MULT ^| DIV ^| MOD ^) signExpression + { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:288:21: ( MULT ^| DIV ^| MOD ^) + int alt13=3; + switch ( input.LA(1) ) { + case MULT: + { + alt13=1; + } + break; + case DIV: + { + alt13=2; + } + break; + case MOD: + { + alt13=3; + } + break; + default: + NoViableAltException nvae = + new NoViableAltException("", 13, 0, input); + throw nvae; + } + switch (alt13) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:288:22: MULT ^ + { + MULT43=(Token)match(input,MULT,FOLLOW_MULT_in_multiplyingExpression1179); + MULT43_tree = (CommonTree)adaptor.create(MULT43); + root_0 = (CommonTree)adaptor.becomeRoot(MULT43_tree, root_0); + + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:288:28: DIV ^ + { + DIV44=(Token)match(input,DIV,FOLLOW_DIV_in_multiplyingExpression1182); + DIV44_tree = (CommonTree)adaptor.create(DIV44); + root_0 = (CommonTree)adaptor.becomeRoot(DIV44_tree, root_0); + + } + break; + case 3 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:288:33: MOD ^ + { + MOD45=(Token)match(input,MOD,FOLLOW_MOD_in_multiplyingExpression1185); + MOD45_tree = (CommonTree)adaptor.create(MOD45); + root_0 = (CommonTree)adaptor.becomeRoot(MOD45_tree, root_0); + + } + break; + + } + + pushFollow(FOLLOW_signExpression_in_multiplyingExpression1189); + signExpression46=signExpression(); + state._fsp--; + + adaptor.addChild(root_0, signExpression46.getTree()); + + } + break; + + default : + break loop14; + } + } + + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "multiplyingExpression" + + + public static class addingExpression_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "addingExpression" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:293:1: addingExpression : multiplyingExpression ( ( PLUS ^| MINUS ^) multiplyingExpression )* ; + public final PropertyParser.addingExpression_return addingExpression() throws Exception { + PropertyParser.addingExpression_return retval = new PropertyParser.addingExpression_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token PLUS48=null; + Token MINUS49=null; + ParserRuleReturnScope multiplyingExpression47 =null; + ParserRuleReturnScope multiplyingExpression50 =null; + + CommonTree PLUS48_tree=null; + CommonTree MINUS49_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:294:3: ( multiplyingExpression ( ( PLUS ^| MINUS ^) multiplyingExpression )* ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:294:5: multiplyingExpression ( ( PLUS ^| MINUS ^) multiplyingExpression )* + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_multiplyingExpression_in_addingExpression1206); + multiplyingExpression47=multiplyingExpression(); + state._fsp--; + + adaptor.addChild(root_0, multiplyingExpression47.getTree()); + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:294:27: ( ( PLUS ^| MINUS ^) multiplyingExpression )* + loop16: + while (true) { + int alt16=2; + int LA16_0 = input.LA(1); + if ( (LA16_0==MINUS||LA16_0==PLUS) ) { + alt16=1; + } + + switch (alt16) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:294:28: ( PLUS ^| MINUS ^) multiplyingExpression + { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:294:28: ( PLUS ^| MINUS ^) + int alt15=2; + int LA15_0 = input.LA(1); + if ( (LA15_0==PLUS) ) { + alt15=1; + } + else if ( (LA15_0==MINUS) ) { + alt15=2; + } + + else { + NoViableAltException nvae = + new NoViableAltException("", 15, 0, input); + throw nvae; + } + + switch (alt15) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:294:29: PLUS ^ + { + PLUS48=(Token)match(input,PLUS,FOLLOW_PLUS_in_addingExpression1210); + PLUS48_tree = (CommonTree)adaptor.create(PLUS48); + root_0 = (CommonTree)adaptor.becomeRoot(PLUS48_tree, root_0); + + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:294:35: MINUS ^ + { + MINUS49=(Token)match(input,MINUS,FOLLOW_MINUS_in_addingExpression1213); + MINUS49_tree = (CommonTree)adaptor.create(MINUS49); + root_0 = (CommonTree)adaptor.becomeRoot(MINUS49_tree, root_0); + + } + break; + + } + + pushFollow(FOLLOW_multiplyingExpression_in_addingExpression1217); + multiplyingExpression50=multiplyingExpression(); + state._fsp--; + + adaptor.addChild(root_0, multiplyingExpression50.getTree()); + + } + break; + + default : + break loop16; + } + } + + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "addingExpression" + + + public static class relationalExpression_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "relationalExpression" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:298:1: relationalExpression : addingExpression ( ( EQUAL ^| NOT_EQUAL ^| GET ^| GETEQ ^| LET ^| LETEQ ^| SAMEAS ^) addingExpression )* ; + public final PropertyParser.relationalExpression_return relationalExpression() throws Exception { + PropertyParser.relationalExpression_return retval = new PropertyParser.relationalExpression_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token EQUAL52=null; + Token NOT_EQUAL53=null; + Token GET54=null; + Token GETEQ55=null; + Token LET56=null; + Token LETEQ57=null; + Token SAMEAS58=null; + ParserRuleReturnScope addingExpression51 =null; + ParserRuleReturnScope addingExpression59 =null; + + CommonTree EQUAL52_tree=null; + CommonTree NOT_EQUAL53_tree=null; + CommonTree GET54_tree=null; + CommonTree GETEQ55_tree=null; + CommonTree LET56_tree=null; + CommonTree LETEQ57_tree=null; + CommonTree SAMEAS58_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:299:3: ( addingExpression ( ( EQUAL ^| NOT_EQUAL ^| GET ^| GETEQ ^| LET ^| LETEQ ^| SAMEAS ^) addingExpression )* ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:299:5: addingExpression ( ( EQUAL ^| NOT_EQUAL ^| GET ^| GETEQ ^| LET ^| LETEQ ^| SAMEAS ^) addingExpression )* + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_addingExpression_in_relationalExpression1235); + addingExpression51=addingExpression(); + state._fsp--; + + adaptor.addChild(root_0, addingExpression51.getTree()); + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:299:22: ( ( EQUAL ^| NOT_EQUAL ^| GET ^| GETEQ ^| LET ^| LETEQ ^| SAMEAS ^) addingExpression )* + loop18: + while (true) { + int alt18=2; + int LA18_0 = input.LA(1); + if ( (LA18_0==EQUAL||(LA18_0 >= GET && LA18_0 <= GETEQ)||(LA18_0 >= LET && LA18_0 <= LETEQ)||LA18_0==NOT_EQUAL||LA18_0==SAMEAS) ) { + alt18=1; + } + + switch (alt18) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:299:23: ( EQUAL ^| NOT_EQUAL ^| GET ^| GETEQ ^| LET ^| LETEQ ^| SAMEAS ^) addingExpression + { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:299:23: ( EQUAL ^| NOT_EQUAL ^| GET ^| GETEQ ^| LET ^| LETEQ ^| SAMEAS ^) + int alt17=7; + switch ( input.LA(1) ) { + case EQUAL: + { + alt17=1; + } + break; + case NOT_EQUAL: + { + alt17=2; + } + break; + case GET: + { + alt17=3; + } + break; + case GETEQ: + { + alt17=4; + } + break; + case LET: + { + alt17=5; + } + break; + case LETEQ: + { + alt17=6; + } + break; + case SAMEAS: + { + alt17=7; + } + break; + default: + NoViableAltException nvae = + new NoViableAltException("", 17, 0, input); + throw nvae; + } + switch (alt17) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:299:24: EQUAL ^ + { + EQUAL52=(Token)match(input,EQUAL,FOLLOW_EQUAL_in_relationalExpression1239); + EQUAL52_tree = (CommonTree)adaptor.create(EQUAL52); + root_0 = (CommonTree)adaptor.becomeRoot(EQUAL52_tree, root_0); + + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:299:31: NOT_EQUAL ^ + { + NOT_EQUAL53=(Token)match(input,NOT_EQUAL,FOLLOW_NOT_EQUAL_in_relationalExpression1242); + NOT_EQUAL53_tree = (CommonTree)adaptor.create(NOT_EQUAL53); + root_0 = (CommonTree)adaptor.becomeRoot(NOT_EQUAL53_tree, root_0); + + } + break; + case 3 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:299:42: GET ^ + { + GET54=(Token)match(input,GET,FOLLOW_GET_in_relationalExpression1245); + GET54_tree = (CommonTree)adaptor.create(GET54); + root_0 = (CommonTree)adaptor.becomeRoot(GET54_tree, root_0); + + } + break; + case 4 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:299:47: GETEQ ^ + { + GETEQ55=(Token)match(input,GETEQ,FOLLOW_GETEQ_in_relationalExpression1248); + GETEQ55_tree = (CommonTree)adaptor.create(GETEQ55); + root_0 = (CommonTree)adaptor.becomeRoot(GETEQ55_tree, root_0); + + } + break; + case 5 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:299:54: LET ^ + { + LET56=(Token)match(input,LET,FOLLOW_LET_in_relationalExpression1251); + LET56_tree = (CommonTree)adaptor.create(LET56); + root_0 = (CommonTree)adaptor.becomeRoot(LET56_tree, root_0); + + } + break; + case 6 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:299:59: LETEQ ^ + { + LETEQ57=(Token)match(input,LETEQ,FOLLOW_LETEQ_in_relationalExpression1254); + LETEQ57_tree = (CommonTree)adaptor.create(LETEQ57); + root_0 = (CommonTree)adaptor.becomeRoot(LETEQ57_tree, root_0); + + } + break; + case 7 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:299:66: SAMEAS ^ + { + SAMEAS58=(Token)match(input,SAMEAS,FOLLOW_SAMEAS_in_relationalExpression1257); + SAMEAS58_tree = (CommonTree)adaptor.create(SAMEAS58); + root_0 = (CommonTree)adaptor.becomeRoot(SAMEAS58_tree, root_0); + + } + break; + + } + + pushFollow(FOLLOW_addingExpression_in_relationalExpression1261); + addingExpression59=addingExpression(); + state._fsp--; + + adaptor.addChild(root_0, addingExpression59.getTree()); + + } + break; + + default : + break loop18; + } + } + + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "relationalExpression" + + + public static class logicalExpression_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "logicalExpression" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:302:1: logicalExpression : relationalExpression ( ( AND ^| OR ^) relationalExpression )* ; + public final PropertyParser.logicalExpression_return logicalExpression() throws Exception { + PropertyParser.logicalExpression_return retval = new PropertyParser.logicalExpression_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token AND61=null; + Token OR62=null; + ParserRuleReturnScope relationalExpression60 =null; + ParserRuleReturnScope relationalExpression63 =null; + + CommonTree AND61_tree=null; + CommonTree OR62_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:303:4: ( relationalExpression ( ( AND ^| OR ^) relationalExpression )* ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:303:6: relationalExpression ( ( AND ^| OR ^) relationalExpression )* + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_relationalExpression_in_logicalExpression1277); + relationalExpression60=relationalExpression(); + state._fsp--; + + adaptor.addChild(root_0, relationalExpression60.getTree()); + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:303:27: ( ( AND ^| OR ^) relationalExpression )* + loop20: + while (true) { + int alt20=2; + int LA20_0 = input.LA(1); + if ( (LA20_0==AND||LA20_0==OR) ) { + alt20=1; + } + + switch (alt20) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:303:28: ( AND ^| OR ^) relationalExpression + { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:303:28: ( AND ^| OR ^) + int alt19=2; + int LA19_0 = input.LA(1); + if ( (LA19_0==AND) ) { + alt19=1; + } + else if ( (LA19_0==OR) ) { + alt19=2; + } + + else { + NoViableAltException nvae = + new NoViableAltException("", 19, 0, input); + throw nvae; + } + + switch (alt19) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:303:29: AND ^ + { + AND61=(Token)match(input,AND,FOLLOW_AND_in_logicalExpression1281); + AND61_tree = (CommonTree)adaptor.create(AND61); + root_0 = (CommonTree)adaptor.becomeRoot(AND61_tree, root_0); + + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:303:34: OR ^ + { + OR62=(Token)match(input,OR,FOLLOW_OR_in_logicalExpression1284); + OR62_tree = (CommonTree)adaptor.create(OR62); + root_0 = (CommonTree)adaptor.becomeRoot(OR62_tree, root_0); + + } + break; + + } + + pushFollow(FOLLOW_relationalExpression_in_logicalExpression1288); + relationalExpression63=relationalExpression(); + state._fsp--; + + adaptor.addChild(root_0, relationalExpression63.getTree()); + + } + break; + + default : + break loop20; + } + } + + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "logicalExpression" + + + public static class unaryExpression_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "unaryExpression" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:309:1: unaryExpression : ( NOT ^)* LPARA ! logicalExpression RPARA !; + public final PropertyParser.unaryExpression_return unaryExpression() throws Exception { + PropertyParser.unaryExpression_return retval = new PropertyParser.unaryExpression_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token NOT64=null; + Token LPARA65=null; + Token RPARA67=null; + ParserRuleReturnScope logicalExpression66 =null; + + CommonTree NOT64_tree=null; + CommonTree LPARA65_tree=null; + CommonTree RPARA67_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:310:3: ( ( NOT ^)* LPARA ! logicalExpression RPARA !) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:310:5: ( NOT ^)* LPARA ! logicalExpression RPARA ! + { + root_0 = (CommonTree)adaptor.nil(); + + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:310:5: ( NOT ^)* + loop21: + while (true) { + int alt21=2; + int LA21_0 = input.LA(1); + if ( (LA21_0==NOT) ) { + alt21=1; + } + + switch (alt21) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:310:6: NOT ^ + { + NOT64=(Token)match(input,NOT,FOLLOW_NOT_in_unaryExpression1308); + NOT64_tree = (CommonTree)adaptor.create(NOT64); + root_0 = (CommonTree)adaptor.becomeRoot(NOT64_tree, root_0); + + } + break; + + default : + break loop21; + } + } + + LPARA65=(Token)match(input,LPARA,FOLLOW_LPARA_in_unaryExpression1314); + pushFollow(FOLLOW_logicalExpression_in_unaryExpression1317); + logicalExpression66=logicalExpression(); + state._fsp--; + + adaptor.addChild(root_0, logicalExpression66.getTree()); + + RPARA67=(Token)match(input,RPARA,FOLLOW_RPARA_in_unaryExpression1319); + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "unaryExpression" + + + public static class combinationalExpression_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "combinationalExpression" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:314:1: combinationalExpression : unaryExpression ( ( AND ^| OR ^) unaryExpression )* ; + public final PropertyParser.combinationalExpression_return combinationalExpression() throws Exception { + PropertyParser.combinationalExpression_return retval = new PropertyParser.combinationalExpression_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token AND69=null; + Token OR70=null; + ParserRuleReturnScope unaryExpression68 =null; + ParserRuleReturnScope unaryExpression71 =null; + + CommonTree AND69_tree=null; + CommonTree OR70_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:315:3: ( unaryExpression ( ( AND ^| OR ^) unaryExpression )* ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:315:3: unaryExpression ( ( AND ^| OR ^) unaryExpression )* + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_unaryExpression_in_combinationalExpression1334); + unaryExpression68=unaryExpression(); + state._fsp--; + + adaptor.addChild(root_0, unaryExpression68.getTree()); + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:315:19: ( ( AND ^| OR ^) unaryExpression )* + loop23: + while (true) { + int alt23=2; + int LA23_0 = input.LA(1); + if ( (LA23_0==AND||LA23_0==OR) ) { + alt23=1; + } + + switch (alt23) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:315:20: ( AND ^| OR ^) unaryExpression + { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:315:20: ( AND ^| OR ^) + int alt22=2; + int LA22_0 = input.LA(1); + if ( (LA22_0==AND) ) { + alt22=1; + } + else if ( (LA22_0==OR) ) { + alt22=2; + } + + else { + NoViableAltException nvae = + new NoViableAltException("", 22, 0, input); + throw nvae; + } + + switch (alt22) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:315:21: AND ^ + { + AND69=(Token)match(input,AND,FOLLOW_AND_in_combinationalExpression1338); + AND69_tree = (CommonTree)adaptor.create(AND69); + root_0 = (CommonTree)adaptor.becomeRoot(AND69_tree, root_0); + + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:315:26: OR ^ + { + OR70=(Token)match(input,OR,FOLLOW_OR_in_combinationalExpression1341); + OR70_tree = (CommonTree)adaptor.create(OR70); + root_0 = (CommonTree)adaptor.becomeRoot(OR70_tree, root_0); + + } + break; + + } + + pushFollow(FOLLOW_unaryExpression_in_combinationalExpression1345); + unaryExpression71=unaryExpression(); + state._fsp--; + + adaptor.addChild(root_0, unaryExpression71.getTree()); + + } + break; + + default : + break loop23; + } + } + + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "combinationalExpression" + + + public static class expression_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "expression" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:317:1: expression : ( combinationalExpression | logicalExpression ); + public final PropertyParser.expression_return expression() throws Exception { + PropertyParser.expression_return retval = new PropertyParser.expression_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + ParserRuleReturnScope combinationalExpression72 =null; + ParserRuleReturnScope logicalExpression73 =null; + + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:325:3: ( combinationalExpression | logicalExpression ) + int alt24=2; + alt24 = dfa24.predict(input); + switch (alt24) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:325:4: combinationalExpression + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_combinationalExpression_in_expression1375); + combinationalExpression72=combinationalExpression(); + state._fsp--; + + adaptor.addChild(root_0, combinationalExpression72.getTree()); + + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:326:5: logicalExpression + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_logicalExpression_in_expression1381); + logicalExpression73=logicalExpression(); + state._fsp--; + + adaptor.addChild(root_0, logicalExpression73.getTree()); + + } + break; + + } + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "expression" + + + public static class constantValue_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "constantValue" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:330:1: constantValue : ( INT | ID | UNIFORM ); + public final PropertyParser.constantValue_return constantValue() throws Exception { + PropertyParser.constantValue_return retval = new PropertyParser.constantValue_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token set74=null; + + CommonTree set74_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:331:2: ( INT | ID | UNIFORM ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g: + { + root_0 = (CommonTree)adaptor.nil(); + + + set74=input.LT(1); + if ( input.LA(1)==ID||input.LA(1)==INT||input.LA(1)==UNIFORM ) { + input.consume(); + adaptor.addChild(root_0, (CommonTree)adaptor.create(set74)); + state.errorRecovery=false; + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + throw mse; + } + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "constantValue" + + + public static class wait_statement_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "wait_statement" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:334:1: wait_statement : ( WAIT ^ LPARA ! expression RPARA ! SEMICOL !| WAIT ^ LPARA ! expression COMMA ! expression RPARA ! SEMICOL !); + public final PropertyParser.wait_statement_return wait_statement() throws Exception { + PropertyParser.wait_statement_return retval = new PropertyParser.wait_statement_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token WAIT75=null; + Token LPARA76=null; + Token RPARA78=null; + Token SEMICOL79=null; + Token WAIT80=null; + Token LPARA81=null; + Token COMMA83=null; + Token RPARA85=null; + Token SEMICOL86=null; + ParserRuleReturnScope expression77 =null; + ParserRuleReturnScope expression82 =null; + ParserRuleReturnScope expression84 =null; + + CommonTree WAIT75_tree=null; + CommonTree LPARA76_tree=null; + CommonTree RPARA78_tree=null; + CommonTree SEMICOL79_tree=null; + CommonTree WAIT80_tree=null; + CommonTree LPARA81_tree=null; + CommonTree COMMA83_tree=null; + CommonTree RPARA85_tree=null; + CommonTree SEMICOL86_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:335:2: ( WAIT ^ LPARA ! expression RPARA ! SEMICOL !| WAIT ^ LPARA ! expression COMMA ! expression RPARA ! SEMICOL !) + int alt25=2; + alt25 = dfa25.predict(input); + switch (alt25) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:335:4: WAIT ^ LPARA ! expression RPARA ! SEMICOL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + WAIT75=(Token)match(input,WAIT,FOLLOW_WAIT_in_wait_statement1414); + WAIT75_tree = (CommonTree)adaptor.create(WAIT75); + root_0 = (CommonTree)adaptor.becomeRoot(WAIT75_tree, root_0); + + LPARA76=(Token)match(input,LPARA,FOLLOW_LPARA_in_wait_statement1417); + pushFollow(FOLLOW_expression_in_wait_statement1420); + expression77=expression(); + state._fsp--; + + adaptor.addChild(root_0, expression77.getTree()); + + RPARA78=(Token)match(input,RPARA,FOLLOW_RPARA_in_wait_statement1422); + SEMICOL79=(Token)match(input,SEMICOL,FOLLOW_SEMICOL_in_wait_statement1425); + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:337:5: WAIT ^ LPARA ! expression COMMA ! expression RPARA ! SEMICOL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + WAIT80=(Token)match(input,WAIT,FOLLOW_WAIT_in_wait_statement1433); + WAIT80_tree = (CommonTree)adaptor.create(WAIT80); + root_0 = (CommonTree)adaptor.becomeRoot(WAIT80_tree, root_0); + + LPARA81=(Token)match(input,LPARA,FOLLOW_LPARA_in_wait_statement1436); + pushFollow(FOLLOW_expression_in_wait_statement1439); + expression82=expression(); + state._fsp--; + + adaptor.addChild(root_0, expression82.getTree()); + + COMMA83=(Token)match(input,COMMA,FOLLOW_COMMA_in_wait_statement1441); + pushFollow(FOLLOW_expression_in_wait_statement1445); + expression84=expression(); + state._fsp--; + + adaptor.addChild(root_0, expression84.getTree()); + + RPARA85=(Token)match(input,RPARA,FOLLOW_RPARA_in_wait_statement1447); + SEMICOL86=(Token)match(input,SEMICOL,FOLLOW_SEMICOL_in_wait_statement1450); + } + break; + + } + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "wait_statement" + + + public static class wait_delay_statement_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "wait_delay_statement" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:340:1: wait_delay_statement : WAIT_DELAY ^ LPARA ! expression RPARA ! SEMICOL !; + public final PropertyParser.wait_delay_statement_return wait_delay_statement() throws Exception { + PropertyParser.wait_delay_statement_return retval = new PropertyParser.wait_delay_statement_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token WAIT_DELAY87=null; + Token LPARA88=null; + Token RPARA90=null; + Token SEMICOL91=null; + ParserRuleReturnScope expression89 =null; + + CommonTree WAIT_DELAY87_tree=null; + CommonTree LPARA88_tree=null; + CommonTree RPARA90_tree=null; + CommonTree SEMICOL91_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:341:3: ( WAIT_DELAY ^ LPARA ! expression RPARA ! SEMICOL !) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:341:5: WAIT_DELAY ^ LPARA ! expression RPARA ! SEMICOL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + WAIT_DELAY87=(Token)match(input,WAIT_DELAY,FOLLOW_WAIT_DELAY_in_wait_delay_statement1465); + WAIT_DELAY87_tree = (CommonTree)adaptor.create(WAIT_DELAY87); + root_0 = (CommonTree)adaptor.becomeRoot(WAIT_DELAY87_tree, root_0); + + LPARA88=(Token)match(input,LPARA,FOLLOW_LPARA_in_wait_delay_statement1468); + pushFollow(FOLLOW_expression_in_wait_delay_statement1471); + expression89=expression(); + state._fsp--; + + adaptor.addChild(root_0, expression89.getTree()); + + RPARA90=(Token)match(input,RPARA,FOLLOW_RPARA_in_wait_delay_statement1473); + SEMICOL91=(Token)match(input,SEMICOL,FOLLOW_SEMICOL_in_wait_delay_statement1476); + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "wait_delay_statement" + + + public static class assert_statement_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "assert_statement" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:344:1: assert_statement : ASSERT ^ LPARA ! expression COMMA ! expression RPARA ! SEMICOL !; + public final PropertyParser.assert_statement_return assert_statement() throws Exception { + PropertyParser.assert_statement_return retval = new PropertyParser.assert_statement_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token ASSERT92=null; + Token LPARA93=null; + Token COMMA95=null; + Token RPARA97=null; + Token SEMICOL98=null; + ParserRuleReturnScope expression94 =null; + ParserRuleReturnScope expression96 =null; + + CommonTree ASSERT92_tree=null; + CommonTree LPARA93_tree=null; + CommonTree COMMA95_tree=null; + CommonTree RPARA97_tree=null; + CommonTree SEMICOL98_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:345:2: ( ASSERT ^ LPARA ! expression COMMA ! expression RPARA ! SEMICOL !) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:345:4: ASSERT ^ LPARA ! expression COMMA ! expression RPARA ! SEMICOL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + ASSERT92=(Token)match(input,ASSERT,FOLLOW_ASSERT_in_assert_statement1489); + ASSERT92_tree = (CommonTree)adaptor.create(ASSERT92); + root_0 = (CommonTree)adaptor.becomeRoot(ASSERT92_tree, root_0); + + LPARA93=(Token)match(input,LPARA,FOLLOW_LPARA_in_assert_statement1492); + pushFollow(FOLLOW_expression_in_assert_statement1495); + expression94=expression(); + state._fsp--; + + adaptor.addChild(root_0, expression94.getTree()); + + COMMA95=(Token)match(input,COMMA,FOLLOW_COMMA_in_assert_statement1497); + pushFollow(FOLLOW_expression_in_assert_statement1500); + expression96=expression(); + state._fsp--; + + adaptor.addChild(root_0, expression96.getTree()); + + RPARA97=(Token)match(input,RPARA,FOLLOW_RPARA_in_assert_statement1502); + SEMICOL98=(Token)match(input,SEMICOL,FOLLOW_SEMICOL_in_assert_statement1505); + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "assert_statement" + + + public static class if_statement_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "if_statement" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:348:1: if_statement : IF ^ if_part ; + public final PropertyParser.if_statement_return if_statement() throws Exception { + PropertyParser.if_statement_return retval = new PropertyParser.if_statement_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token IF99=null; + ParserRuleReturnScope if_part100 =null; + + CommonTree IF99_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:349:3: ( IF ^ if_part ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:349:5: IF ^ if_part + { + root_0 = (CommonTree)adaptor.nil(); + + + IF99=(Token)match(input,IF,FOLLOW_IF_in_if_statement1519); + IF99_tree = (CommonTree)adaptor.create(IF99); + root_0 = (CommonTree)adaptor.becomeRoot(IF99_tree, root_0); + + pushFollow(FOLLOW_if_part_in_if_statement1522); + if_part100=if_part(); + state._fsp--; + + adaptor.addChild(root_0, if_part100.getTree()); + + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "if_statement" + + + public static class if_part_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "if_part" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:352:1: if_part : LPARA ! expression RPARA ! LCURL ! ( statement )* RCURL ! ( else_if )* ( else_part )* ; + public final PropertyParser.if_part_return if_part() throws Exception { + PropertyParser.if_part_return retval = new PropertyParser.if_part_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token LPARA101=null; + Token RPARA103=null; + Token LCURL104=null; + Token RCURL106=null; + ParserRuleReturnScope expression102 =null; + ParserRuleReturnScope statement105 =null; + ParserRuleReturnScope else_if107 =null; + ParserRuleReturnScope else_part108 =null; + + CommonTree LPARA101_tree=null; + CommonTree RPARA103_tree=null; + CommonTree LCURL104_tree=null; + CommonTree RCURL106_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:353:3: ( LPARA ! expression RPARA ! LCURL ! ( statement )* RCURL ! ( else_if )* ( else_part )* ) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:353:5: LPARA ! expression RPARA ! LCURL ! ( statement )* RCURL ! ( else_if )* ( else_part )* + { + root_0 = (CommonTree)adaptor.nil(); + + + LPARA101=(Token)match(input,LPARA,FOLLOW_LPARA_in_if_part1537); + pushFollow(FOLLOW_expression_in_if_part1539); + expression102=expression(); + state._fsp--; + + adaptor.addChild(root_0, expression102.getTree()); + + RPARA103=(Token)match(input,RPARA,FOLLOW_RPARA_in_if_part1541); + LCURL104=(Token)match(input,LCURL,FOLLOW_LCURL_in_if_part1544); + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:353:36: ( statement )* + loop26: + while (true) { + int alt26=2; + int LA26_0 = input.LA(1); + if ( (LA26_0==ALWAYS||(LA26_0 >= ASSERT && LA26_0 <= ASSERT_UNTIL)||LA26_0==IF||LA26_0==SENALWAYS||(LA26_0 >= WAIT && LA26_0 <= WAIT_STABLE)) ) { + alt26=1; + } + + switch (alt26) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:353:37: statement + { + pushFollow(FOLLOW_statement_in_if_part1548); + statement105=statement(); + state._fsp--; + + adaptor.addChild(root_0, statement105.getTree()); + + } + break; + + default : + break loop26; + } + } + + RCURL106=(Token)match(input,RCURL,FOLLOW_RCURL_in_if_part1552); + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:353:56: ( else_if )* + loop27: + while (true) { + int alt27=2; + int LA27_0 = input.LA(1); + if ( (LA27_0==ELSEIF) ) { + alt27=1; + } + + switch (alt27) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:353:57: else_if + { + pushFollow(FOLLOW_else_if_in_if_part1556); + else_if107=else_if(); + state._fsp--; + + adaptor.addChild(root_0, else_if107.getTree()); + + } + break; + + default : + break loop27; + } + } + + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:353:67: ( else_part )* + loop28: + while (true) { + int alt28=2; + int LA28_0 = input.LA(1); + if ( (LA28_0==ELSE) ) { + alt28=1; + } + + switch (alt28) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:353:68: else_part + { + pushFollow(FOLLOW_else_part_in_if_part1561); + else_part108=else_part(); + state._fsp--; + + adaptor.addChild(root_0, else_part108.getTree()); + + } + break; + + default : + break loop28; + } + } + + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "if_part" + + + public static class else_if_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "else_if" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:356:1: else_if : ELSEIF ^ LPARA ! expression RPARA ! LCURL ! ( statement )* RCURL !; + public final PropertyParser.else_if_return else_if() throws Exception { + PropertyParser.else_if_return retval = new PropertyParser.else_if_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token ELSEIF109=null; + Token LPARA110=null; + Token RPARA112=null; + Token LCURL113=null; + Token RCURL115=null; + ParserRuleReturnScope expression111 =null; + ParserRuleReturnScope statement114 =null; + + CommonTree ELSEIF109_tree=null; + CommonTree LPARA110_tree=null; + CommonTree RPARA112_tree=null; + CommonTree LCURL113_tree=null; + CommonTree RCURL115_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:357:2: ( ELSEIF ^ LPARA ! expression RPARA ! LCURL ! ( statement )* RCURL !) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:357:4: ELSEIF ^ LPARA ! expression RPARA ! LCURL ! ( statement )* RCURL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + ELSEIF109=(Token)match(input,ELSEIF,FOLLOW_ELSEIF_in_else_if1575); + ELSEIF109_tree = (CommonTree)adaptor.create(ELSEIF109); + root_0 = (CommonTree)adaptor.becomeRoot(ELSEIF109_tree, root_0); + + LPARA110=(Token)match(input,LPARA,FOLLOW_LPARA_in_else_if1579); + pushFollow(FOLLOW_expression_in_else_if1581); + expression111=expression(); + state._fsp--; + + adaptor.addChild(root_0, expression111.getTree()); + + RPARA112=(Token)match(input,RPARA,FOLLOW_RPARA_in_else_if1583); + LCURL113=(Token)match(input,LCURL,FOLLOW_LCURL_in_else_if1587); + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:357:45: ( statement )* + loop29: + while (true) { + int alt29=2; + int LA29_0 = input.LA(1); + if ( (LA29_0==ALWAYS||(LA29_0 >= ASSERT && LA29_0 <= ASSERT_UNTIL)||LA29_0==IF||LA29_0==SENALWAYS||(LA29_0 >= WAIT && LA29_0 <= WAIT_STABLE)) ) { + alt29=1; + } + + switch (alt29) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:357:46: statement + { + pushFollow(FOLLOW_statement_in_else_if1591); + statement114=statement(); + state._fsp--; + + adaptor.addChild(root_0, statement114.getTree()); + + } + break; + + default : + break loop29; + } + } + + RCURL115=(Token)match(input,RCURL,FOLLOW_RCURL_in_else_if1596); + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "else_if" + + + public static class else_part_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "else_part" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:360:1: else_part : ELSE ^ LCURL ! ( statement )* RCURL !; + public final PropertyParser.else_part_return else_part() throws Exception { + PropertyParser.else_part_return retval = new PropertyParser.else_part_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token ELSE116=null; + Token LCURL117=null; + Token RCURL119=null; + ParserRuleReturnScope statement118 =null; + + CommonTree ELSE116_tree=null; + CommonTree LCURL117_tree=null; + CommonTree RCURL119_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:361:2: ( ELSE ^ LCURL ! ( statement )* RCURL !) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:361:3: ELSE ^ LCURL ! ( statement )* RCURL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + ELSE116=(Token)match(input,ELSE,FOLLOW_ELSE_in_else_part1609); + ELSE116_tree = (CommonTree)adaptor.create(ELSE116); + root_0 = (CommonTree)adaptor.becomeRoot(ELSE116_tree, root_0); + + LCURL117=(Token)match(input,LCURL,FOLLOW_LCURL_in_else_part1613); + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:361:17: ( statement )* + loop30: + while (true) { + int alt30=2; + int LA30_0 = input.LA(1); + if ( (LA30_0==ALWAYS||(LA30_0 >= ASSERT && LA30_0 <= ASSERT_UNTIL)||LA30_0==IF||LA30_0==SENALWAYS||(LA30_0 >= WAIT && LA30_0 <= WAIT_STABLE)) ) { + alt30=1; + } + + switch (alt30) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:361:18: statement + { + pushFollow(FOLLOW_statement_in_else_part1617); + statement118=statement(); + state._fsp--; + + adaptor.addChild(root_0, statement118.getTree()); + + } + break; + + default : + break loop30; + } + } + + RCURL119=(Token)match(input,RCURL,FOLLOW_RCURL_in_else_part1622); + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "else_part" + + + public static class waitStable_statement_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "waitStable_statement" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:364:1: waitStable_statement : WAIT_STABLE ^ LPARA ! expression COMMA ! expression RPARA ! SEMICOL !; + public final PropertyParser.waitStable_statement_return waitStable_statement() throws Exception { + PropertyParser.waitStable_statement_return retval = new PropertyParser.waitStable_statement_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token WAIT_STABLE120=null; + Token LPARA121=null; + Token COMMA123=null; + Token RPARA125=null; + Token SEMICOL126=null; + ParserRuleReturnScope expression122 =null; + ParserRuleReturnScope expression124 =null; + + CommonTree WAIT_STABLE120_tree=null; + CommonTree LPARA121_tree=null; + CommonTree COMMA123_tree=null; + CommonTree RPARA125_tree=null; + CommonTree SEMICOL126_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:365:2: ( WAIT_STABLE ^ LPARA ! expression COMMA ! expression RPARA ! SEMICOL !) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:365:2: WAIT_STABLE ^ LPARA ! expression COMMA ! expression RPARA ! SEMICOL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + WAIT_STABLE120=(Token)match(input,WAIT_STABLE,FOLLOW_WAIT_STABLE_in_waitStable_statement1634); + WAIT_STABLE120_tree = (CommonTree)adaptor.create(WAIT_STABLE120); + root_0 = (CommonTree)adaptor.becomeRoot(WAIT_STABLE120_tree, root_0); + + LPARA121=(Token)match(input,LPARA,FOLLOW_LPARA_in_waitStable_statement1637); + pushFollow(FOLLOW_expression_in_waitStable_statement1640); + expression122=expression(); + state._fsp--; + + adaptor.addChild(root_0, expression122.getTree()); + + COMMA123=(Token)match(input,COMMA,FOLLOW_COMMA_in_waitStable_statement1642); + pushFollow(FOLLOW_expression_in_waitStable_statement1645); + expression124=expression(); + state._fsp--; + + adaptor.addChild(root_0, expression124.getTree()); + + RPARA125=(Token)match(input,RPARA,FOLLOW_RPARA_in_waitStable_statement1647); + SEMICOL126=(Token)match(input,SEMICOL,FOLLOW_SEMICOL_in_waitStable_statement1650); + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "waitStable_statement" + + + public static class assertUntil_statement_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "assertUntil_statement" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:367:1: assertUntil_statement : ASSERT_UNTIL ^ LPARA ! expression COMMA ! expression RPARA ! SEMICOL !; + public final PropertyParser.assertUntil_statement_return assertUntil_statement() throws Exception { + PropertyParser.assertUntil_statement_return retval = new PropertyParser.assertUntil_statement_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token ASSERT_UNTIL127=null; + Token LPARA128=null; + Token COMMA130=null; + Token RPARA132=null; + Token SEMICOL133=null; + ParserRuleReturnScope expression129 =null; + ParserRuleReturnScope expression131 =null; + + CommonTree ASSERT_UNTIL127_tree=null; + CommonTree LPARA128_tree=null; + CommonTree COMMA130_tree=null; + CommonTree RPARA132_tree=null; + CommonTree SEMICOL133_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:368:2: ( ASSERT_UNTIL ^ LPARA ! expression COMMA ! expression RPARA ! SEMICOL !) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:368:2: ASSERT_UNTIL ^ LPARA ! expression COMMA ! expression RPARA ! SEMICOL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + ASSERT_UNTIL127=(Token)match(input,ASSERT_UNTIL,FOLLOW_ASSERT_UNTIL_in_assertUntil_statement1658); + ASSERT_UNTIL127_tree = (CommonTree)adaptor.create(ASSERT_UNTIL127); + root_0 = (CommonTree)adaptor.becomeRoot(ASSERT_UNTIL127_tree, root_0); + + LPARA128=(Token)match(input,LPARA,FOLLOW_LPARA_in_assertUntil_statement1661); + pushFollow(FOLLOW_expression_in_assertUntil_statement1664); + expression129=expression(); + state._fsp--; + + adaptor.addChild(root_0, expression129.getTree()); + + COMMA130=(Token)match(input,COMMA,FOLLOW_COMMA_in_assertUntil_statement1666); + pushFollow(FOLLOW_expression_in_assertUntil_statement1669); + expression131=expression(); + state._fsp--; + + adaptor.addChild(root_0, expression131.getTree()); + + RPARA132=(Token)match(input,RPARA,FOLLOW_RPARA_in_assertUntil_statement1671); + SEMICOL133=(Token)match(input,SEMICOL,FOLLOW_SEMICOL_in_assertUntil_statement1674); + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "assertUntil_statement" + + + public static class edge_statement_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "edge_statement" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:371:1: edge_statement : WAIT_POSEDGE ^ LPARA ! expression RPARA ! SEMICOL !; + public final PropertyParser.edge_statement_return edge_statement() throws Exception { + PropertyParser.edge_statement_return retval = new PropertyParser.edge_statement_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token WAIT_POSEDGE134=null; + Token LPARA135=null; + Token RPARA137=null; + Token SEMICOL138=null; + ParserRuleReturnScope expression136 =null; + + CommonTree WAIT_POSEDGE134_tree=null; + CommonTree LPARA135_tree=null; + CommonTree RPARA137_tree=null; + CommonTree SEMICOL138_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:372:3: ( WAIT_POSEDGE ^ LPARA ! expression RPARA ! SEMICOL !) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:372:3: WAIT_POSEDGE ^ LPARA ! expression RPARA ! SEMICOL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + WAIT_POSEDGE134=(Token)match(input,WAIT_POSEDGE,FOLLOW_WAIT_POSEDGE_in_edge_statement1684); + WAIT_POSEDGE134_tree = (CommonTree)adaptor.create(WAIT_POSEDGE134); + root_0 = (CommonTree)adaptor.becomeRoot(WAIT_POSEDGE134_tree, root_0); + + LPARA135=(Token)match(input,LPARA,FOLLOW_LPARA_in_edge_statement1687); + pushFollow(FOLLOW_expression_in_edge_statement1690); + expression136=expression(); + state._fsp--; + + adaptor.addChild(root_0, expression136.getTree()); + + RPARA137=(Token)match(input,RPARA,FOLLOW_RPARA_in_edge_statement1692); + SEMICOL138=(Token)match(input,SEMICOL,FOLLOW_SEMICOL_in_edge_statement1695); + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "edge_statement" + + + public static class assertStable_statement_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "assertStable_statement" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:374:1: assertStable_statement : ASSERT_STABLE ^ LPARA ! expression COMMA ! expression RPARA ! SEMICOL !; + public final PropertyParser.assertStable_statement_return assertStable_statement() throws Exception { + PropertyParser.assertStable_statement_return retval = new PropertyParser.assertStable_statement_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + Token ASSERT_STABLE139=null; + Token LPARA140=null; + Token COMMA142=null; + Token RPARA144=null; + Token SEMICOL145=null; + ParserRuleReturnScope expression141 =null; + ParserRuleReturnScope expression143 =null; + + CommonTree ASSERT_STABLE139_tree=null; + CommonTree LPARA140_tree=null; + CommonTree COMMA142_tree=null; + CommonTree RPARA144_tree=null; + CommonTree SEMICOL145_tree=null; + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:375:2: ( ASSERT_STABLE ^ LPARA ! expression COMMA ! expression RPARA ! SEMICOL !) + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:375:2: ASSERT_STABLE ^ LPARA ! expression COMMA ! expression RPARA ! SEMICOL ! + { + root_0 = (CommonTree)adaptor.nil(); + + + ASSERT_STABLE139=(Token)match(input,ASSERT_STABLE,FOLLOW_ASSERT_STABLE_in_assertStable_statement1703); + ASSERT_STABLE139_tree = (CommonTree)adaptor.create(ASSERT_STABLE139); + root_0 = (CommonTree)adaptor.becomeRoot(ASSERT_STABLE139_tree, root_0); + + LPARA140=(Token)match(input,LPARA,FOLLOW_LPARA_in_assertStable_statement1706); + pushFollow(FOLLOW_expression_in_assertStable_statement1709); + expression141=expression(); + state._fsp--; + + adaptor.addChild(root_0, expression141.getTree()); + + COMMA142=(Token)match(input,COMMA,FOLLOW_COMMA_in_assertStable_statement1711); + pushFollow(FOLLOW_expression_in_assertStable_statement1714); + expression143=expression(); + state._fsp--; + + adaptor.addChild(root_0, expression143.getTree()); + + RPARA144=(Token)match(input,RPARA,FOLLOW_RPARA_in_assertStable_statement1716); + SEMICOL145=(Token)match(input,SEMICOL,FOLLOW_SEMICOL_in_assertStable_statement1719); + } + + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "assertStable_statement" + + + public static class statement_return extends ParserRuleReturnScope { + CommonTree tree; + @Override + public CommonTree getTree() { return tree; } + }; + + + // $ANTLR start "statement" + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:383:1: statement : ( wait_statement | wait_delay_statement | assert_statement | if_statement | waitStable_statement | assertUntil_statement | always_statement | assertStable_statement | edge_statement | senalways_statement ); + public final PropertyParser.statement_return statement() throws Exception { + PropertyParser.statement_return retval = new PropertyParser.statement_return(); + retval.start = input.LT(1); + + CommonTree root_0 = null; + + ParserRuleReturnScope wait_statement146 =null; + ParserRuleReturnScope wait_delay_statement147 =null; + ParserRuleReturnScope assert_statement148 =null; + ParserRuleReturnScope if_statement149 =null; + ParserRuleReturnScope waitStable_statement150 =null; + ParserRuleReturnScope assertUntil_statement151 =null; + ParserRuleReturnScope always_statement152 =null; + ParserRuleReturnScope assertStable_statement153 =null; + ParserRuleReturnScope edge_statement154 =null; + ParserRuleReturnScope senalways_statement155 =null; + + + try { + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:384:2: ( wait_statement | wait_delay_statement | assert_statement | if_statement | waitStable_statement | assertUntil_statement | always_statement | assertStable_statement | edge_statement | senalways_statement ) + int alt31=10; + switch ( input.LA(1) ) { + case WAIT: + { + alt31=1; + } + break; + case WAIT_DELAY: + { + alt31=2; + } + break; + case ASSERT: + { + alt31=3; + } + break; + case IF: + { + alt31=4; + } + break; + case WAIT_STABLE: + { + alt31=5; + } + break; + case ASSERT_UNTIL: + { + alt31=6; + } + break; + case ALWAYS: + { + alt31=7; + } + break; + case ASSERT_STABLE: + { + alt31=8; + } + break; + case WAIT_POSEDGE: + { + alt31=9; + } + break; + case SENALWAYS: + { + alt31=10; + } + break; + default: + NoViableAltException nvae = + new NoViableAltException("", 31, 0, input); + throw nvae; + } + switch (alt31) { + case 1 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:384:3: wait_statement + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_wait_statement_in_statement1734); + wait_statement146=wait_statement(); + state._fsp--; + + adaptor.addChild(root_0, wait_statement146.getTree()); + + } + break; + case 2 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:385:3: wait_delay_statement + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_wait_delay_statement_in_statement1738); + wait_delay_statement147=wait_delay_statement(); + state._fsp--; + + adaptor.addChild(root_0, wait_delay_statement147.getTree()); + + } + break; + case 3 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:386:3: assert_statement + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_assert_statement_in_statement1742); + assert_statement148=assert_statement(); + state._fsp--; + + adaptor.addChild(root_0, assert_statement148.getTree()); + + } + break; + case 4 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:387:3: if_statement + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_if_statement_in_statement1746); + if_statement149=if_statement(); + state._fsp--; + + adaptor.addChild(root_0, if_statement149.getTree()); + + } + break; + case 5 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:388:3: waitStable_statement + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_waitStable_statement_in_statement1750); + waitStable_statement150=waitStable_statement(); + state._fsp--; + + adaptor.addChild(root_0, waitStable_statement150.getTree()); + + } + break; + case 6 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:389:3: assertUntil_statement + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_assertUntil_statement_in_statement1754); + assertUntil_statement151=assertUntil_statement(); + state._fsp--; + + adaptor.addChild(root_0, assertUntil_statement151.getTree()); + + } + break; + case 7 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:390:3: always_statement + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_always_statement_in_statement1758); + always_statement152=always_statement(); + state._fsp--; + + adaptor.addChild(root_0, always_statement152.getTree()); + + } + break; + case 8 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:391:3: assertStable_statement + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_assertStable_statement_in_statement1762); + assertStable_statement153=assertStable_statement(); + state._fsp--; + + adaptor.addChild(root_0, assertStable_statement153.getTree()); + + } + break; + case 9 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:392:3: edge_statement + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_edge_statement_in_statement1766); + edge_statement154=edge_statement(); + state._fsp--; + + adaptor.addChild(root_0, edge_statement154.getTree()); + + } + break; + case 10 : + // /Users/myers/research/nobackup/workspace/BioSim/gui/src/lpn/parser/properties/Property.g:393:3: senalways_statement + { + root_0 = (CommonTree)adaptor.nil(); + + + pushFollow(FOLLOW_senalways_statement_in_statement1770); + senalways_statement155=senalways_statement(); + state._fsp--; + + adaptor.addChild(root_0, senalways_statement155.getTree()); + + } + break; + + } + retval.stop = input.LT(-1); + + retval.tree = (CommonTree)adaptor.rulePostProcessing(root_0); + adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); + + } + catch (RecognitionException re) { + reportError(re); + recover(input,re); + retval.tree = (CommonTree)adaptor.errorNode(input, retval.start, input.LT(-1), re); + } + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "statement" + + // Delegated rules + + + protected DFA24 dfa24 = new DFA24(this); + protected DFA25 dfa25 = new DFA25(this); + static final String DFA24_eotS = + "\4\uffff"; + static final String DFA24_eofS = + "\4\uffff"; + static final String DFA24_minS = + "\2\30\2\uffff"; + static final String DFA24_maxS = + "\2\60\2\uffff"; + static final String DFA24_acceptS = + "\2\uffff\1\1\1\2"; + static final String DFA24_specialS = + "\4\uffff}>"; + static final String[] DFA24_transitionS = { + "\1\3\1\uffff\1\3\4\uffff\1\2\1\3\2\uffff\1\1\3\uffff\1\3\10\uffff\1\3", + "\1\3\1\uffff\1\3\4\uffff\1\2\3\uffff\1\1\14\uffff\1\3", + "", + "" + }; + + static final short[] DFA24_eot = DFA.unpackEncodedString(DFA24_eotS); + static final short[] DFA24_eof = DFA.unpackEncodedString(DFA24_eofS); + static final char[] DFA24_min = DFA.unpackEncodedStringToUnsignedChars(DFA24_minS); + static final char[] DFA24_max = DFA.unpackEncodedStringToUnsignedChars(DFA24_maxS); + static final short[] DFA24_accept = DFA.unpackEncodedString(DFA24_acceptS); + static final short[] DFA24_special = DFA.unpackEncodedString(DFA24_specialS); + static final short[][] DFA24_transition; + + static { + int numStates = DFA24_transitionS.length; + DFA24_transition = new short[numStates][]; + for (int i=0; i"; + static final String[] DFA25_transitionS = { + "\1\1", + "\1\2", + "\1\7\1\uffff\1\7\4\uffff\1\4\1\6\2\uffff\1\3\3\uffff\1\5\10\uffff\1"+ + "\7", + "\1\7\1\uffff\1\7\4\uffff\1\4\3\uffff\1\3\14\uffff\1\7", + "\1\13\1\uffff\1\13\5\uffff\1\11\2\uffff\1\12\3\uffff\1\10\10\uffff\1"+ + "\13", + "\1\7\1\uffff\1\7\5\uffff\1\6\2\uffff\1\14\3\uffff\1\5\10\uffff\1\7", + "\1\7\1\uffff\1\7\5\uffff\1\6\2\uffff\1\14\3\uffff\1\5\10\uffff\1\7", + "\1\31\4\uffff\1\34\2\uffff\1\16\3\uffff\1\22\3\uffff\1\24\1\25\6\uffff"+ + "\1\26\1\27\1\uffff\1\21\1\17\1\15\1\uffff\1\23\1\uffff\1\32\1\20\2\uffff"+ + "\1\33\1\30", + "\1\13\1\uffff\1\13\5\uffff\1\11\2\uffff\1\12\3\uffff\1\10\10\uffff\1"+ + "\13", + "\1\13\1\uffff\1\13\5\uffff\1\11\2\uffff\1\12\3\uffff\1\10\10\uffff\1"+ + "\13", + "\1\13\1\uffff\1\13\10\uffff\1\12\14\uffff\1\13", + "\1\51\7\uffff\1\36\3\uffff\1\42\3\uffff\1\44\1\45\6\uffff\1\46\1\47"+ + "\1\uffff\1\41\1\37\1\35\1\uffff\1\43\1\uffff\1\52\1\40\2\uffff\1\53\1"+ + "\50", + "\1\7\1\uffff\1\7\10\uffff\1\14\14\uffff\1\7", + "\1\57\1\uffff\1\57\5\uffff\1\55\2\uffff\1\56\3\uffff\1\54\10\uffff\1"+ + "\57", + "\1\57\1\uffff\1\57\5\uffff\1\55\2\uffff\1\56\3\uffff\1\54\10\uffff\1"+ + "\57", + "\1\57\1\uffff\1\57\5\uffff\1\55\2\uffff\1\56\3\uffff\1\54\10\uffff\1"+ + "\57", + "\1\63\1\uffff\1\63\5\uffff\1\61\2\uffff\1\62\3\uffff\1\60\10\uffff\1"+ + "\63", + "\1\63\1\uffff\1\63\5\uffff\1\61\2\uffff\1\62\3\uffff\1\60\10\uffff\1"+ + "\63", + "\1\67\1\uffff\1\67\5\uffff\1\65\2\uffff\1\66\3\uffff\1\64\10\uffff\1"+ + "\67", + "\1\67\1\uffff\1\67\5\uffff\1\65\2\uffff\1\66\3\uffff\1\64\10\uffff\1"+ + "\67", + "\1\67\1\uffff\1\67\5\uffff\1\65\2\uffff\1\66\3\uffff\1\64\10\uffff\1"+ + "\67", + "\1\67\1\uffff\1\67\5\uffff\1\65\2\uffff\1\66\3\uffff\1\64\10\uffff\1"+ + "\67", + "\1\67\1\uffff\1\67\5\uffff\1\65\2\uffff\1\66\3\uffff\1\64\10\uffff\1"+ + "\67", + "\1\67\1\uffff\1\67\5\uffff\1\65\2\uffff\1\66\3\uffff\1\64\10\uffff\1"+ + "\67", + "\1\67\1\uffff\1\67\5\uffff\1\65\2\uffff\1\66\3\uffff\1\64\10\uffff\1"+ + "\67", + "\1\73\1\uffff\1\73\5\uffff\1\71\2\uffff\1\72\3\uffff\1\70\10\uffff\1"+ + "\73", + "\1\73\1\uffff\1\73\5\uffff\1\71\2\uffff\1\72\3\uffff\1\70\10\uffff\1"+ + "\73", + "", + "", + "\1\77\1\uffff\1\77\5\uffff\1\75\2\uffff\1\76\3\uffff\1\74\10\uffff\1"+ + "\77", + "\1\77\1\uffff\1\77\5\uffff\1\75\2\uffff\1\76\3\uffff\1\74\10\uffff\1"+ + "\77", + "\1\77\1\uffff\1\77\5\uffff\1\75\2\uffff\1\76\3\uffff\1\74\10\uffff\1"+ + "\77", + "\1\103\1\uffff\1\103\5\uffff\1\101\2\uffff\1\102\3\uffff\1\100\10\uffff"+ + "\1\103", + "\1\103\1\uffff\1\103\5\uffff\1\101\2\uffff\1\102\3\uffff\1\100\10\uffff"+ + "\1\103", + "\1\107\1\uffff\1\107\5\uffff\1\105\2\uffff\1\106\3\uffff\1\104\10\uffff"+ + "\1\107", + "\1\107\1\uffff\1\107\5\uffff\1\105\2\uffff\1\106\3\uffff\1\104\10\uffff"+ + "\1\107", + "\1\107\1\uffff\1\107\5\uffff\1\105\2\uffff\1\106\3\uffff\1\104\10\uffff"+ + "\1\107", + "\1\107\1\uffff\1\107\5\uffff\1\105\2\uffff\1\106\3\uffff\1\104\10\uffff"+ + "\1\107", + "\1\107\1\uffff\1\107\5\uffff\1\105\2\uffff\1\106\3\uffff\1\104\10\uffff"+ + "\1\107", + "\1\107\1\uffff\1\107\5\uffff\1\105\2\uffff\1\106\3\uffff\1\104\10\uffff"+ + "\1\107", + "\1\107\1\uffff\1\107\5\uffff\1\105\2\uffff\1\106\3\uffff\1\104\10\uffff"+ + "\1\107", + "\1\113\1\uffff\1\113\5\uffff\1\111\2\uffff\1\112\3\uffff\1\110\10\uffff"+ + "\1\113", + "\1\113\1\uffff\1\113\5\uffff\1\111\2\uffff\1\112\3\uffff\1\110\10\uffff"+ + "\1\113", + "\1\114\4\uffff\1\34\33\uffff\1\115\3\uffff\1\33", + "\1\57\1\uffff\1\57\5\uffff\1\55\2\uffff\1\56\3\uffff\1\54\10\uffff\1"+ + "\57", + "\1\57\1\uffff\1\57\5\uffff\1\55\2\uffff\1\56\3\uffff\1\54\10\uffff\1"+ + "\57", + "\1\57\1\uffff\1\57\10\uffff\1\56\14\uffff\1\57", + "\1\31\4\uffff\1\34\2\uffff\1\16\3\uffff\1\22\3\uffff\1\24\1\25\6\uffff"+ + "\1\26\1\27\1\uffff\1\21\1\17\1\15\1\uffff\1\23\1\uffff\1\32\1\20\2\uffff"+ + "\1\33\1\30", + "\1\63\1\uffff\1\63\5\uffff\1\61\2\uffff\1\62\3\uffff\1\60\10\uffff\1"+ + "\63", + "\1\63\1\uffff\1\63\5\uffff\1\61\2\uffff\1\62\3\uffff\1\60\10\uffff\1"+ + "\63", + "\1\63\1\uffff\1\63\10\uffff\1\62\14\uffff\1\63", + "\1\31\4\uffff\1\34\2\uffff\1\117\3\uffff\1\22\3\uffff\1\24\1\25\6\uffff"+ + "\1\26\1\27\1\uffff\1\21\1\120\1\116\1\uffff\1\23\1\uffff\1\32\1\20\2"+ + "\uffff\1\33\1\30", + "\1\67\1\uffff\1\67\5\uffff\1\65\2\uffff\1\66\3\uffff\1\64\10\uffff\1"+ + "\67", + "\1\67\1\uffff\1\67\5\uffff\1\65\2\uffff\1\66\3\uffff\1\64\10\uffff\1"+ + "\67", + "\1\67\1\uffff\1\67\10\uffff\1\66\14\uffff\1\67", + "\1\31\4\uffff\1\34\2\uffff\1\122\3\uffff\1\22\3\uffff\1\24\1\25\6\uffff"+ + "\1\26\1\27\1\uffff\1\125\1\123\1\121\1\uffff\1\23\1\uffff\1\32\1\124"+ + "\2\uffff\1\33\1\30", + "\1\73\1\uffff\1\73\5\uffff\1\71\2\uffff\1\72\3\uffff\1\70\10\uffff\1"+ + "\73", + "\1\73\1\uffff\1\73\5\uffff\1\71\2\uffff\1\72\3\uffff\1\70\10\uffff\1"+ + "\73", + "\1\73\1\uffff\1\73\10\uffff\1\72\14\uffff\1\73", + "\1\31\4\uffff\1\34\2\uffff\1\127\3\uffff\1\133\3\uffff\1\135\1\136\6"+ + "\uffff\1\137\1\140\1\uffff\1\132\1\130\1\126\1\uffff\1\134\1\uffff\1"+ + "\32\1\131\2\uffff\1\33\1\141", + "\1\77\1\uffff\1\77\5\uffff\1\75\2\uffff\1\76\3\uffff\1\74\10\uffff\1"+ + "\77", + "\1\77\1\uffff\1\77\5\uffff\1\75\2\uffff\1\76\3\uffff\1\74\10\uffff\1"+ + "\77", + "\1\77\1\uffff\1\77\10\uffff\1\76\14\uffff\1\77", + "\1\51\7\uffff\1\36\3\uffff\1\42\3\uffff\1\44\1\45\6\uffff\1\46\1\47"+ + "\1\uffff\1\41\1\37\1\35\1\uffff\1\43\1\uffff\1\52\1\40\2\uffff\1\53\1"+ + "\50", + "\1\103\1\uffff\1\103\5\uffff\1\101\2\uffff\1\102\3\uffff\1\100\10\uffff"+ + "\1\103", + "\1\103\1\uffff\1\103\5\uffff\1\101\2\uffff\1\102\3\uffff\1\100\10\uffff"+ + "\1\103", + "\1\103\1\uffff\1\103\10\uffff\1\102\14\uffff\1\103", + "\1\51\7\uffff\1\143\3\uffff\1\42\3\uffff\1\44\1\45\6\uffff\1\46\1\47"+ + "\1\uffff\1\41\1\144\1\142\1\uffff\1\43\1\uffff\1\52\1\40\2\uffff\1\53"+ + "\1\50", + "\1\107\1\uffff\1\107\5\uffff\1\105\2\uffff\1\106\3\uffff\1\104\10\uffff"+ + "\1\107", + "\1\107\1\uffff\1\107\5\uffff\1\105\2\uffff\1\106\3\uffff\1\104\10\uffff"+ + "\1\107", + "\1\107\1\uffff\1\107\10\uffff\1\106\14\uffff\1\107", + "\1\51\7\uffff\1\146\3\uffff\1\42\3\uffff\1\44\1\45\6\uffff\1\46\1\47"+ + "\1\uffff\1\151\1\147\1\145\1\uffff\1\43\1\uffff\1\52\1\150\2\uffff\1"+ + "\53\1\50", + "\1\113\1\uffff\1\113\5\uffff\1\111\2\uffff\1\112\3\uffff\1\110\10\uffff"+ + "\1\113", + "\1\113\1\uffff\1\113\5\uffff\1\111\2\uffff\1\112\3\uffff\1\110\10\uffff"+ + "\1\113", + "\1\113\1\uffff\1\113\10\uffff\1\112\14\uffff\1\113", + "\1\51\7\uffff\1\153\3\uffff\1\157\3\uffff\1\161\1\162\6\uffff\1\163"+ + "\1\164\1\uffff\1\156\1\154\1\152\1\uffff\1\160\1\uffff\1\52\1\155\2\uffff"+ + "\1\53\1\165", + "\1\167\3\uffff\1\166", + "\1\167\3\uffff\1\166", + "\1\173\1\uffff\1\173\5\uffff\1\171\2\uffff\1\172\3\uffff\1\170\10\uffff"+ + "\1\173", + "\1\173\1\uffff\1\173\5\uffff\1\171\2\uffff\1\172\3\uffff\1\170\10\uffff"+ + "\1\173", + "\1\173\1\uffff\1\173\5\uffff\1\171\2\uffff\1\172\3\uffff\1\170\10\uffff"+ + "\1\173", + "\1\177\1\uffff\1\177\5\uffff\1\175\2\uffff\1\176\3\uffff\1\174\10\uffff"+ + "\1\177", + "\1\177\1\uffff\1\177\5\uffff\1\175\2\uffff\1\176\3\uffff\1\174\10\uffff"+ + "\1\177", + "\1\177\1\uffff\1\177\5\uffff\1\175\2\uffff\1\176\3\uffff\1\174\10\uffff"+ + "\1\177", + "\1\u0083\1\uffff\1\u0083\5\uffff\1\u0081\2\uffff\1\u0082\3\uffff\1\u0080"+ + "\10\uffff\1\u0083", + "\1\u0083\1\uffff\1\u0083\5\uffff\1\u0081\2\uffff\1\u0082\3\uffff\1\u0080"+ + "\10\uffff\1\u0083", + "\1\u0087\1\uffff\1\u0087\5\uffff\1\u0085\2\uffff\1\u0086\3\uffff\1\u0084"+ + "\10\uffff\1\u0087", + "\1\u0087\1\uffff\1\u0087\5\uffff\1\u0085\2\uffff\1\u0086\3\uffff\1\u0084"+ + "\10\uffff\1\u0087", + "\1\u0087\1\uffff\1\u0087\5\uffff\1\u0085\2\uffff\1\u0086\3\uffff\1\u0084"+ + "\10\uffff\1\u0087", + "\1\u008b\1\uffff\1\u008b\5\uffff\1\u0089\2\uffff\1\u008a\3\uffff\1\u0088"+ + "\10\uffff\1\u008b", + "\1\u008b\1\uffff\1\u008b\5\uffff\1\u0089\2\uffff\1\u008a\3\uffff\1\u0088"+ + "\10\uffff\1\u008b", + "\1\u008f\1\uffff\1\u008f\5\uffff\1\u008d\2\uffff\1\u008e\3\uffff\1\u008c"+ + "\10\uffff\1\u008f", + "\1\u008f\1\uffff\1\u008f\5\uffff\1\u008d\2\uffff\1\u008e\3\uffff\1\u008c"+ + "\10\uffff\1\u008f", + "\1\u008f\1\uffff\1\u008f\5\uffff\1\u008d\2\uffff\1\u008e\3\uffff\1\u008c"+ + "\10\uffff\1\u008f", + "\1\u008f\1\uffff\1\u008f\5\uffff\1\u008d\2\uffff\1\u008e\3\uffff\1\u008c"+ + "\10\uffff\1\u008f", + "\1\u008f\1\uffff\1\u008f\5\uffff\1\u008d\2\uffff\1\u008e\3\uffff\1\u008c"+ + "\10\uffff\1\u008f", + "\1\u008f\1\uffff\1\u008f\5\uffff\1\u008d\2\uffff\1\u008e\3\uffff\1\u008c"+ + "\10\uffff\1\u008f", + "\1\u008f\1\uffff\1\u008f\5\uffff\1\u008d\2\uffff\1\u008e\3\uffff\1\u008c"+ + "\10\uffff\1\u008f", + "\1\u0093\1\uffff\1\u0093\5\uffff\1\u0091\2\uffff\1\u0092\3\uffff\1\u0090"+ + "\10\uffff\1\u0093", + "\1\u0093\1\uffff\1\u0093\5\uffff\1\u0091\2\uffff\1\u0092\3\uffff\1\u0090"+ + "\10\uffff\1\u0093", + "\1\u0093\1\uffff\1\u0093\5\uffff\1\u0091\2\uffff\1\u0092\3\uffff\1\u0090"+ + "\10\uffff\1\u0093", + "\1\u0097\1\uffff\1\u0097\5\uffff\1\u0095\2\uffff\1\u0096\3\uffff\1\u0094"+ + "\10\uffff\1\u0097", + "\1\u0097\1\uffff\1\u0097\5\uffff\1\u0095\2\uffff\1\u0096\3\uffff\1\u0094"+ + "\10\uffff\1\u0097", + "\1\u0097\1\uffff\1\u0097\5\uffff\1\u0095\2\uffff\1\u0096\3\uffff\1\u0094"+ + "\10\uffff\1\u0097", + "\1\u009b\1\uffff\1\u009b\5\uffff\1\u0099\2\uffff\1\u009a\3\uffff\1\u0098"+ + "\10\uffff\1\u009b", + "\1\u009b\1\uffff\1\u009b\5\uffff\1\u0099\2\uffff\1\u009a\3\uffff\1\u0098"+ + "\10\uffff\1\u009b", + "\1\u009f\1\uffff\1\u009f\5\uffff\1\u009d\2\uffff\1\u009e\3\uffff\1\u009c"+ + "\10\uffff\1\u009f", + "\1\u009f\1\uffff\1\u009f\5\uffff\1\u009d\2\uffff\1\u009e\3\uffff\1\u009c"+ + "\10\uffff\1\u009f", + "\1\u009f\1\uffff\1\u009f\5\uffff\1\u009d\2\uffff\1\u009e\3\uffff\1\u009c"+ + "\10\uffff\1\u009f", + "\1\u00a3\1\uffff\1\u00a3\5\uffff\1\u00a1\2\uffff\1\u00a2\3\uffff\1\u00a0"+ + "\10\uffff\1\u00a3", + "\1\u00a3\1\uffff\1\u00a3\5\uffff\1\u00a1\2\uffff\1\u00a2\3\uffff\1\u00a0"+ + "\10\uffff\1\u00a3", + "\1\u00a7\1\uffff\1\u00a7\5\uffff\1\u00a5\2\uffff\1\u00a6\3\uffff\1\u00a4"+ + "\10\uffff\1\u00a7", + "\1\u00a7\1\uffff\1\u00a7\5\uffff\1\u00a5\2\uffff\1\u00a6\3\uffff\1\u00a4"+ + "\10\uffff\1\u00a7", + "\1\u00a7\1\uffff\1\u00a7\5\uffff\1\u00a5\2\uffff\1\u00a6\3\uffff\1\u00a4"+ + "\10\uffff\1\u00a7", + "\1\u00a7\1\uffff\1\u00a7\5\uffff\1\u00a5\2\uffff\1\u00a6\3\uffff\1\u00a4"+ + "\10\uffff\1\u00a7", + "\1\u00a7\1\uffff\1\u00a7\5\uffff\1\u00a5\2\uffff\1\u00a6\3\uffff\1\u00a4"+ + "\10\uffff\1\u00a7", + "\1\u00a7\1\uffff\1\u00a7\5\uffff\1\u00a5\2\uffff\1\u00a6\3\uffff\1\u00a4"+ + "\10\uffff\1\u00a7", + "\1\u00a7\1\uffff\1\u00a7\5\uffff\1\u00a5\2\uffff\1\u00a6\3\uffff\1\u00a4"+ + "\10\uffff\1\u00a7", + "\1\167\3\uffff\1\166", + "\1\u00ab\1\uffff\1\u00ab\5\uffff\1\u00a9\2\uffff\1\u00aa\3\uffff\1\u00a8"+ + "\10\uffff\1\u00ab", + "\1\173\1\uffff\1\173\5\uffff\1\171\2\uffff\1\172\3\uffff\1\170\10\uffff"+ + "\1\173", + "\1\173\1\uffff\1\173\5\uffff\1\171\2\uffff\1\172\3\uffff\1\170\10\uffff"+ + "\1\173", + "\1\173\1\uffff\1\173\10\uffff\1\172\14\uffff\1\173", + "\1\31\4\uffff\1\34\2\uffff\1\117\3\uffff\1\22\3\uffff\1\24\1\25\6\uffff"+ + "\1\26\1\27\1\uffff\1\21\1\120\1\116\1\uffff\1\23\1\uffff\1\32\1\20\2"+ + "\uffff\1\33\1\30", + "\1\177\1\uffff\1\177\5\uffff\1\175\2\uffff\1\176\3\uffff\1\174\10\uffff"+ + "\1\177", + "\1\177\1\uffff\1\177\5\uffff\1\175\2\uffff\1\176\3\uffff\1\174\10\uffff"+ + "\1\177", + "\1\177\1\uffff\1\177\10\uffff\1\176\14\uffff\1\177", + "\1\31\4\uffff\1\34\2\uffff\1\122\3\uffff\1\22\3\uffff\1\24\1\25\6\uffff"+ + "\1\26\1\27\1\uffff\1\125\1\123\1\121\1\uffff\1\23\1\uffff\1\32\1\124"+ + "\2\uffff\1\33\1\30", + "\1\u0083\1\uffff\1\u0083\5\uffff\1\u0081\2\uffff\1\u0082\3\uffff\1\u0080"+ + "\10\uffff\1\u0083", + "\1\u0083\1\uffff\1\u0083\5\uffff\1\u0081\2\uffff\1\u0082\3\uffff\1\u0080"+ + "\10\uffff\1\u0083", + "\1\u0083\1\uffff\1\u0083\10\uffff\1\u0082\14\uffff\1\u0083", + "\1\31\4\uffff\1\34\2\uffff\1\u00ad\3\uffff\1\22\3\uffff\1\24\1\25\6"+ + "\uffff\1\26\1\27\1\uffff\1\125\1\u00ae\1\u00ac\1\uffff\1\23\1\uffff\1"+ + "\32\1\124\2\uffff\1\33\1\30", + "\1\u0087\1\uffff\1\u0087\5\uffff\1\u0085\2\uffff\1\u0086\3\uffff\1\u0084"+ + "\10\uffff\1\u0087", + "\1\u0087\1\uffff\1\u0087\5\uffff\1\u0085\2\uffff\1\u0086\3\uffff\1\u0084"+ + "\10\uffff\1\u0087", + "\1\u0087\1\uffff\1\u0087\10\uffff\1\u0086\14\uffff\1\u0087", + "\1\31\4\uffff\1\34\2\uffff\1\127\3\uffff\1\133\3\uffff\1\135\1\136\6"+ + "\uffff\1\137\1\140\1\uffff\1\132\1\130\1\126\1\uffff\1\134\1\uffff\1"+ + "\32\1\131\2\uffff\1\33\1\141", + "\1\u008b\1\uffff\1\u008b\5\uffff\1\u0089\2\uffff\1\u008a\3\uffff\1\u0088"+ + "\10\uffff\1\u008b", + "\1\u008b\1\uffff\1\u008b\5\uffff\1\u0089\2\uffff\1\u008a\3\uffff\1\u0088"+ + "\10\uffff\1\u008b", + "\1\u008b\1\uffff\1\u008b\10\uffff\1\u008a\14\uffff\1\u008b", + "\1\31\4\uffff\1\34\2\uffff\1\u00b0\3\uffff\1\133\3\uffff\1\135\1\136"+ + "\6\uffff\1\137\1\140\1\uffff\1\132\1\u00b1\1\u00af\1\uffff\1\134\1\uffff"+ + "\1\32\1\131\2\uffff\1\33\1\141", + "\1\u008f\1\uffff\1\u008f\5\uffff\1\u008d\2\uffff\1\u008e\3\uffff\1\u008c"+ + "\10\uffff\1\u008f", + "\1\u008f\1\uffff\1\u008f\5\uffff\1\u008d\2\uffff\1\u008e\3\uffff\1\u008c"+ + "\10\uffff\1\u008f", + "\1\u008f\1\uffff\1\u008f\10\uffff\1\u008e\14\uffff\1\u008f", + "\1\31\4\uffff\1\34\2\uffff\1\u00b3\3\uffff\1\133\3\uffff\1\135\1\136"+ + "\6\uffff\1\137\1\140\1\uffff\1\u00b6\1\u00b4\1\u00b2\1\uffff\1\134\1"+ + "\uffff\1\32\1\u00b5\2\uffff\1\33\1\141", + "\1\u0093\1\uffff\1\u0093\5\uffff\1\u0091\2\uffff\1\u0092\3\uffff\1\u0090"+ + "\10\uffff\1\u0093", + "\1\u0093\1\uffff\1\u0093\5\uffff\1\u0091\2\uffff\1\u0092\3\uffff\1\u0090"+ + "\10\uffff\1\u0093", + "\1\u0093\1\uffff\1\u0093\10\uffff\1\u0092\14\uffff\1\u0093", + "\1\51\7\uffff\1\143\3\uffff\1\42\3\uffff\1\44\1\45\6\uffff\1\46\1\47"+ + "\1\uffff\1\41\1\144\1\142\1\uffff\1\43\1\uffff\1\52\1\40\2\uffff\1\53"+ + "\1\50", + "\1\u0097\1\uffff\1\u0097\5\uffff\1\u0095\2\uffff\1\u0096\3\uffff\1\u0094"+ + "\10\uffff\1\u0097", + "\1\u0097\1\uffff\1\u0097\5\uffff\1\u0095\2\uffff\1\u0096\3\uffff\1\u0094"+ + "\10\uffff\1\u0097", + "\1\u0097\1\uffff\1\u0097\10\uffff\1\u0096\14\uffff\1\u0097", + "\1\51\7\uffff\1\146\3\uffff\1\42\3\uffff\1\44\1\45\6\uffff\1\46\1\47"+ + "\1\uffff\1\151\1\147\1\145\1\uffff\1\43\1\uffff\1\52\1\150\2\uffff\1"+ + "\53\1\50", + "\1\u009b\1\uffff\1\u009b\5\uffff\1\u0099\2\uffff\1\u009a\3\uffff\1\u0098"+ + "\10\uffff\1\u009b", + "\1\u009b\1\uffff\1\u009b\5\uffff\1\u0099\2\uffff\1\u009a\3\uffff\1\u0098"+ + "\10\uffff\1\u009b", + "\1\u009b\1\uffff\1\u009b\10\uffff\1\u009a\14\uffff\1\u009b", + "\1\51\7\uffff\1\u00b8\3\uffff\1\42\3\uffff\1\44\1\45\6\uffff\1\46\1"+ + "\47\1\uffff\1\151\1\u00b9\1\u00b7\1\uffff\1\43\1\uffff\1\52\1\150\2\uffff"+ + "\1\53\1\50", + "\1\u009f\1\uffff\1\u009f\5\uffff\1\u009d\2\uffff\1\u009e\3\uffff\1\u009c"+ + "\10\uffff\1\u009f", + "\1\u009f\1\uffff\1\u009f\5\uffff\1\u009d\2\uffff\1\u009e\3\uffff\1\u009c"+ + "\10\uffff\1\u009f", + "\1\u009f\1\uffff\1\u009f\10\uffff\1\u009e\14\uffff\1\u009f", + "\1\51\7\uffff\1\153\3\uffff\1\157\3\uffff\1\161\1\162\6\uffff\1\163"+ + "\1\164\1\uffff\1\156\1\154\1\152\1\uffff\1\160\1\uffff\1\52\1\155\2\uffff"+ + "\1\53\1\165", + "\1\u00a3\1\uffff\1\u00a3\5\uffff\1\u00a1\2\uffff\1\u00a2\3\uffff\1\u00a0"+ + "\10\uffff\1\u00a3", + "\1\u00a3\1\uffff\1\u00a3\5\uffff\1\u00a1\2\uffff\1\u00a2\3\uffff\1\u00a0"+ + "\10\uffff\1\u00a3", + "\1\u00a3\1\uffff\1\u00a3\10\uffff\1\u00a2\14\uffff\1\u00a3", + "\1\51\7\uffff\1\u00bb\3\uffff\1\157\3\uffff\1\161\1\162\6\uffff\1\163"+ + "\1\164\1\uffff\1\156\1\u00bc\1\u00ba\1\uffff\1\160\1\uffff\1\52\1\155"+ + "\2\uffff\1\53\1\165", + "\1\u00a7\1\uffff\1\u00a7\5\uffff\1\u00a5\2\uffff\1\u00a6\3\uffff\1\u00a4"+ + "\10\uffff\1\u00a7", + "\1\u00a7\1\uffff\1\u00a7\5\uffff\1\u00a5\2\uffff\1\u00a6\3\uffff\1\u00a4"+ + "\10\uffff\1\u00a7", + "\1\u00a7\1\uffff\1\u00a7\10\uffff\1\u00a6\14\uffff\1\u00a7", + "\1\51\7\uffff\1\u00be\3\uffff\1\157\3\uffff\1\161\1\162\6\uffff\1\163"+ + "\1\164\1\uffff\1\u00c1\1\u00bf\1\u00bd\1\uffff\1\160\1\uffff\1\52\1\u00c0"+ + "\2\uffff\1\53\1\165", + "\1\u00ab\1\uffff\1\u00ab\5\uffff\1\u00a9\2\uffff\1\u00aa\3\uffff\1\u00a8"+ + "\10\uffff\1\u00ab", + "\1\u00ab\1\uffff\1\u00ab\5\uffff\1\u00a9\2\uffff\1\u00aa\3\uffff\1\u00a8"+ + "\10\uffff\1\u00ab", + "\1\u00ab\1\uffff\1\u00ab\10\uffff\1\u00aa\14\uffff\1\u00ab", + "\1\u00ce\7\uffff\1\u00c3\3\uffff\1\u00c7\3\uffff\1\u00c9\1\u00ca\6\uffff"+ + "\1\u00cb\1\u00cc\1\uffff\1\u00c6\1\u00c4\1\u00c2\1\uffff\1\u00c8\1\uffff"+ + "\1\u00cf\1\u00c5\2\uffff\1\u00d0\1\u00cd", + "\1\u00d4\1\uffff\1\u00d4\5\uffff\1\u00d2\2\uffff\1\u00d3\3\uffff\1\u00d1"+ + "\10\uffff\1\u00d4", + "\1\u00d4\1\uffff\1\u00d4\5\uffff\1\u00d2\2\uffff\1\u00d3\3\uffff\1\u00d1"+ + "\10\uffff\1\u00d4", + "\1\u00d4\1\uffff\1\u00d4\5\uffff\1\u00d2\2\uffff\1\u00d3\3\uffff\1\u00d1"+ + "\10\uffff\1\u00d4", + "\1\u00d8\1\uffff\1\u00d8\5\uffff\1\u00d6\2\uffff\1\u00d7\3\uffff\1\u00d5"+ + "\10\uffff\1\u00d8", + "\1\u00d8\1\uffff\1\u00d8\5\uffff\1\u00d6\2\uffff\1\u00d7\3\uffff\1\u00d5"+ + "\10\uffff\1\u00d8", + "\1\u00d8\1\uffff\1\u00d8\5\uffff\1\u00d6\2\uffff\1\u00d7\3\uffff\1\u00d5"+ + "\10\uffff\1\u00d8", + "\1\u00dc\1\uffff\1\u00dc\5\uffff\1\u00da\2\uffff\1\u00db\3\uffff\1\u00d9"+ + "\10\uffff\1\u00dc", + "\1\u00dc\1\uffff\1\u00dc\5\uffff\1\u00da\2\uffff\1\u00db\3\uffff\1\u00d9"+ + "\10\uffff\1\u00dc", + "\1\u00dc\1\uffff\1\u00dc\5\uffff\1\u00da\2\uffff\1\u00db\3\uffff\1\u00d9"+ + "\10\uffff\1\u00dc", + "\1\u00e0\1\uffff\1\u00e0\5\uffff\1\u00de\2\uffff\1\u00df\3\uffff\1\u00dd"+ + "\10\uffff\1\u00e0", + "\1\u00e0\1\uffff\1\u00e0\5\uffff\1\u00de\2\uffff\1\u00df\3\uffff\1\u00dd"+ + "\10\uffff\1\u00e0", + "\1\u00e4\1\uffff\1\u00e4\5\uffff\1\u00e2\2\uffff\1\u00e3\3\uffff\1\u00e1"+ + "\10\uffff\1\u00e4", + "\1\u00e4\1\uffff\1\u00e4\5\uffff\1\u00e2\2\uffff\1\u00e3\3\uffff\1\u00e1"+ + "\10\uffff\1\u00e4", + "\1\u00e4\1\uffff\1\u00e4\5\uffff\1\u00e2\2\uffff\1\u00e3\3\uffff\1\u00e1"+ + "\10\uffff\1\u00e4", + "\1\u00e8\1\uffff\1\u00e8\5\uffff\1\u00e6\2\uffff\1\u00e7\3\uffff\1\u00e5"+ + "\10\uffff\1\u00e8", + "\1\u00e8\1\uffff\1\u00e8\5\uffff\1\u00e6\2\uffff\1\u00e7\3\uffff\1\u00e5"+ + "\10\uffff\1\u00e8", + "\1\u00e8\1\uffff\1\u00e8\5\uffff\1\u00e6\2\uffff\1\u00e7\3\uffff\1\u00e5"+ + "\10\uffff\1\u00e8", + "\1\u00ec\1\uffff\1\u00ec\5\uffff\1\u00ea\2\uffff\1\u00eb\3\uffff\1\u00e9"+ + "\10\uffff\1\u00ec", + "\1\u00ec\1\uffff\1\u00ec\5\uffff\1\u00ea\2\uffff\1\u00eb\3\uffff\1\u00e9"+ + "\10\uffff\1\u00ec", + "\1\u00ec\1\uffff\1\u00ec\5\uffff\1\u00ea\2\uffff\1\u00eb\3\uffff\1\u00e9"+ + "\10\uffff\1\u00ec", + "\1\u00f0\1\uffff\1\u00f0\5\uffff\1\u00ee\2\uffff\1\u00ef\3\uffff\1\u00ed"+ + "\10\uffff\1\u00f0", + "\1\u00f0\1\uffff\1\u00f0\5\uffff\1\u00ee\2\uffff\1\u00ef\3\uffff\1\u00ed"+ + "\10\uffff\1\u00f0", + "\1\u00f4\1\uffff\1\u00f4\5\uffff\1\u00f2\2\uffff\1\u00f3\3\uffff\1\u00f1"+ + "\10\uffff\1\u00f4", + "\1\u00f4\1\uffff\1\u00f4\5\uffff\1\u00f2\2\uffff\1\u00f3\3\uffff\1\u00f1"+ + "\10\uffff\1\u00f4", + "\1\u00f4\1\uffff\1\u00f4\5\uffff\1\u00f2\2\uffff\1\u00f3\3\uffff\1\u00f1"+ + "\10\uffff\1\u00f4", + "\1\u00f8\1\uffff\1\u00f8\5\uffff\1\u00f6\2\uffff\1\u00f7\3\uffff\1\u00f5"+ + "\10\uffff\1\u00f8", + "\1\u00f8\1\uffff\1\u00f8\5\uffff\1\u00f6\2\uffff\1\u00f7\3\uffff\1\u00f5"+ + "\10\uffff\1\u00f8", + "\1\u00fc\1\uffff\1\u00fc\5\uffff\1\u00fa\2\uffff\1\u00fb\3\uffff\1\u00f9"+ + "\10\uffff\1\u00fc", + "\1\u00fc\1\uffff\1\u00fc\5\uffff\1\u00fa\2\uffff\1\u00fb\3\uffff\1\u00f9"+ + "\10\uffff\1\u00fc", + "\1\u00fc\1\uffff\1\u00fc\5\uffff\1\u00fa\2\uffff\1\u00fb\3\uffff\1\u00f9"+ + "\10\uffff\1\u00fc", + "\1\u00fc\1\uffff\1\u00fc\5\uffff\1\u00fa\2\uffff\1\u00fb\3\uffff\1\u00f9"+ + "\10\uffff\1\u00fc", + "\1\u00fc\1\uffff\1\u00fc\5\uffff\1\u00fa\2\uffff\1\u00fb\3\uffff\1\u00f9"+ + "\10\uffff\1\u00fc", + "\1\u00fc\1\uffff\1\u00fc\5\uffff\1\u00fa\2\uffff\1\u00fb\3\uffff\1\u00f9"+ + "\10\uffff\1\u00fc", + "\1\u00fc\1\uffff\1\u00fc\5\uffff\1\u00fa\2\uffff\1\u00fb\3\uffff\1\u00f9"+ + "\10\uffff\1\u00fc", + "\1\u0100\1\uffff\1\u0100\5\uffff\1\u00fe\2\uffff\1\u00ff\3\uffff\1\u00fd"+ + "\10\uffff\1\u0100", + "\1\u0100\1\uffff\1\u0100\5\uffff\1\u00fe\2\uffff\1\u00ff\3\uffff\1\u00fd"+ + "\10\uffff\1\u0100", + "\1\114\4\uffff\1\34\33\uffff\1\115\3\uffff\1\33", + "\1\u00d4\1\uffff\1\u00d4\5\uffff\1\u00d2\2\uffff\1\u00d3\3\uffff\1\u00d1"+ + "\10\uffff\1\u00d4", + "\1\u00d4\1\uffff\1\u00d4\5\uffff\1\u00d2\2\uffff\1\u00d3\3\uffff\1\u00d1"+ + "\10\uffff\1\u00d4", + "\1\u00d4\1\uffff\1\u00d4\10\uffff\1\u00d3\14\uffff\1\u00d4", + "\1\31\4\uffff\1\34\2\uffff\1\u00ad\3\uffff\1\22\3\uffff\1\24\1\25\6"+ + "\uffff\1\26\1\27\1\uffff\1\125\1\u00ae\1\u00ac\1\uffff\1\23\1\uffff\1"+ + "\32\1\124\2\uffff\1\33\1\30", + "\1\u00d8\1\uffff\1\u00d8\5\uffff\1\u00d6\2\uffff\1\u00d7\3\uffff\1\u00d5"+ + "\10\uffff\1\u00d8", + "\1\u00d8\1\uffff\1\u00d8\5\uffff\1\u00d6\2\uffff\1\u00d7\3\uffff\1\u00d5"+ + "\10\uffff\1\u00d8", + "\1\u00d8\1\uffff\1\u00d8\10\uffff\1\u00d7\14\uffff\1\u00d8", + "\1\31\4\uffff\1\34\2\uffff\1\u00b0\3\uffff\1\133\3\uffff\1\135\1\136"+ + "\6\uffff\1\137\1\140\1\uffff\1\132\1\u00b1\1\u00af\1\uffff\1\134\1\uffff"+ + "\1\32\1\131\2\uffff\1\33\1\141", + "\1\u00dc\1\uffff\1\u00dc\5\uffff\1\u00da\2\uffff\1\u00db\3\uffff\1\u00d9"+ + "\10\uffff\1\u00dc", + "\1\u00dc\1\uffff\1\u00dc\5\uffff\1\u00da\2\uffff\1\u00db\3\uffff\1\u00d9"+ + "\10\uffff\1\u00dc", + "\1\u00dc\1\uffff\1\u00dc\10\uffff\1\u00db\14\uffff\1\u00dc", + "\1\31\4\uffff\1\34\2\uffff\1\u00b3\3\uffff\1\133\3\uffff\1\135\1\136"+ + "\6\uffff\1\137\1\140\1\uffff\1\u00b6\1\u00b4\1\u00b2\1\uffff\1\134\1"+ + "\uffff\1\32\1\u00b5\2\uffff\1\33\1\141", + "\1\u00e0\1\uffff\1\u00e0\5\uffff\1\u00de\2\uffff\1\u00df\3\uffff\1\u00dd"+ + "\10\uffff\1\u00e0", + "\1\u00e0\1\uffff\1\u00e0\5\uffff\1\u00de\2\uffff\1\u00df\3\uffff\1\u00dd"+ + "\10\uffff\1\u00e0", + "\1\u00e0\1\uffff\1\u00e0\10\uffff\1\u00df\14\uffff\1\u00e0", + "\1\31\4\uffff\1\34\2\uffff\1\u0102\3\uffff\1\133\3\uffff\1\135\1\136"+ + "\6\uffff\1\137\1\140\1\uffff\1\u00b6\1\u0103\1\u0101\1\uffff\1\134\1"+ + "\uffff\1\32\1\u00b5\2\uffff\1\33\1\141", + "\1\u00e4\1\uffff\1\u00e4\5\uffff\1\u00e2\2\uffff\1\u00e3\3\uffff\1\u00e1"+ + "\10\uffff\1\u00e4", + "\1\u00e4\1\uffff\1\u00e4\5\uffff\1\u00e2\2\uffff\1\u00e3\3\uffff\1\u00e1"+ + "\10\uffff\1\u00e4", + "\1\u00e4\1\uffff\1\u00e4\10\uffff\1\u00e3\14\uffff\1\u00e4", + "\1\51\7\uffff\1\u00b8\3\uffff\1\42\3\uffff\1\44\1\45\6\uffff\1\46\1"+ + "\47\1\uffff\1\151\1\u00b9\1\u00b7\1\uffff\1\43\1\uffff\1\52\1\150\2\uffff"+ + "\1\53\1\50", + "\1\u00e8\1\uffff\1\u00e8\5\uffff\1\u00e6\2\uffff\1\u00e7\3\uffff\1\u00e5"+ + "\10\uffff\1\u00e8", + "\1\u00e8\1\uffff\1\u00e8\5\uffff\1\u00e6\2\uffff\1\u00e7\3\uffff\1\u00e5"+ + "\10\uffff\1\u00e8", + "\1\u00e8\1\uffff\1\u00e8\10\uffff\1\u00e7\14\uffff\1\u00e8", + "\1\51\7\uffff\1\u00bb\3\uffff\1\157\3\uffff\1\161\1\162\6\uffff\1\163"+ + "\1\164\1\uffff\1\156\1\u00bc\1\u00ba\1\uffff\1\160\1\uffff\1\52\1\155"+ + "\2\uffff\1\53\1\165", + "\1\u00ec\1\uffff\1\u00ec\5\uffff\1\u00ea\2\uffff\1\u00eb\3\uffff\1\u00e9"+ + "\10\uffff\1\u00ec", + "\1\u00ec\1\uffff\1\u00ec\5\uffff\1\u00ea\2\uffff\1\u00eb\3\uffff\1\u00e9"+ + "\10\uffff\1\u00ec", + "\1\u00ec\1\uffff\1\u00ec\10\uffff\1\u00eb\14\uffff\1\u00ec", + "\1\51\7\uffff\1\u00be\3\uffff\1\157\3\uffff\1\161\1\162\6\uffff\1\163"+ + "\1\164\1\uffff\1\u00c1\1\u00bf\1\u00bd\1\uffff\1\160\1\uffff\1\52\1\u00c0"+ + "\2\uffff\1\53\1\165", + "\1\u00f0\1\uffff\1\u00f0\5\uffff\1\u00ee\2\uffff\1\u00ef\3\uffff\1\u00ed"+ + "\10\uffff\1\u00f0", + "\1\u00f0\1\uffff\1\u00f0\5\uffff\1\u00ee\2\uffff\1\u00ef\3\uffff\1\u00ed"+ + "\10\uffff\1\u00f0", + "\1\u00f0\1\uffff\1\u00f0\10\uffff\1\u00ef\14\uffff\1\u00f0", + "\1\51\7\uffff\1\u0105\3\uffff\1\157\3\uffff\1\161\1\162\6\uffff\1\163"+ + "\1\164\1\uffff\1\u00c1\1\u0106\1\u0104\1\uffff\1\160\1\uffff\1\52\1\u00c0"+ + "\2\uffff\1\53\1\165", + "\1\u00f4\1\uffff\1\u00f4\5\uffff\1\u00f2\2\uffff\1\u00f3\3\uffff\1\u00f1"+ + "\10\uffff\1\u00f4", + "\1\u00f4\1\uffff\1\u00f4\5\uffff\1\u00f2\2\uffff\1\u00f3\3\uffff\1\u00f1"+ + "\10\uffff\1\u00f4", + "\1\u00f4\1\uffff\1\u00f4\10\uffff\1\u00f3\14\uffff\1\u00f4", + "\1\u00ce\7\uffff\1\u00c3\3\uffff\1\u00c7\3\uffff\1\u00c9\1\u00ca\6\uffff"+ + "\1\u00cb\1\u00cc\1\uffff\1\u00c6\1\u00c4\1\u00c2\1\uffff\1\u00c8\1\uffff"+ + "\1\u00cf\1\u00c5\2\uffff\1\u00d0\1\u00cd", + "\1\u00f8\1\uffff\1\u00f8\5\uffff\1\u00f6\2\uffff\1\u00f7\3\uffff\1\u00f5"+ + "\10\uffff\1\u00f8", + "\1\u00f8\1\uffff\1\u00f8\5\uffff\1\u00f6\2\uffff\1\u00f7\3\uffff\1\u00f5"+ + "\10\uffff\1\u00f8", + "\1\u00f8\1\uffff\1\u00f8\10\uffff\1\u00f7\14\uffff\1\u00f8", + "\1\u00ce\7\uffff\1\u0108\3\uffff\1\u00c7\3\uffff\1\u00c9\1\u00ca\6\uffff"+ + "\1\u00cb\1\u00cc\1\uffff\1\u00c6\1\u0109\1\u0107\1\uffff\1\u00c8\1\uffff"+ + "\1\u00cf\1\u00c5\2\uffff\1\u00d0\1\u00cd", + "\1\u00fc\1\uffff\1\u00fc\5\uffff\1\u00fa\2\uffff\1\u00fb\3\uffff\1\u00f9"+ + "\10\uffff\1\u00fc", + "\1\u00fc\1\uffff\1\u00fc\5\uffff\1\u00fa\2\uffff\1\u00fb\3\uffff\1\u00f9"+ + "\10\uffff\1\u00fc", + "\1\u00fc\1\uffff\1\u00fc\10\uffff\1\u00fb\14\uffff\1\u00fc", + "\1\u00ce\7\uffff\1\u010b\3\uffff\1\u00c7\3\uffff\1\u00c9\1\u00ca\6\uffff"+ + "\1\u00cb\1\u00cc\1\uffff\1\u010e\1\u010c\1\u010a\1\uffff\1\u00c8\1\uffff"+ + "\1\u00cf\1\u010d\2\uffff\1\u00d0\1\u00cd", + "\1\u0100\1\uffff\1\u0100\5\uffff\1\u00fe\2\uffff\1\u00ff\3\uffff\1\u00fd"+ + "\10\uffff\1\u0100", + "\1\u0100\1\uffff\1\u0100\5\uffff\1\u00fe\2\uffff\1\u00ff\3\uffff\1\u00fd"+ + "\10\uffff\1\u0100", + "\1\u0100\1\uffff\1\u0100\10\uffff\1\u00ff\14\uffff\1\u0100", + "\1\u00ce\7\uffff\1\u0110\3\uffff\1\u0114\3\uffff\1\u0116\1\u0117\6\uffff"+ + "\1\u0118\1\u0119\1\uffff\1\u0113\1\u0111\1\u010f\1\uffff\1\u0115\1\uffff"+ + "\1\u00cf\1\u0112\2\uffff\1\u00d0\1\u011a", + "\1\u011e\1\uffff\1\u011e\5\uffff\1\u011c\2\uffff\1\u011d\3\uffff\1\u011b"+ + "\10\uffff\1\u011e", + "\1\u011e\1\uffff\1\u011e\5\uffff\1\u011c\2\uffff\1\u011d\3\uffff\1\u011b"+ + "\10\uffff\1\u011e", + "\1\u011e\1\uffff\1\u011e\5\uffff\1\u011c\2\uffff\1\u011d\3\uffff\1\u011b"+ + "\10\uffff\1\u011e", + "\1\u0122\1\uffff\1\u0122\5\uffff\1\u0120\2\uffff\1\u0121\3\uffff\1\u011f"+ + "\10\uffff\1\u0122", + "\1\u0122\1\uffff\1\u0122\5\uffff\1\u0120\2\uffff\1\u0121\3\uffff\1\u011f"+ + "\10\uffff\1\u0122", + "\1\u0122\1\uffff\1\u0122\5\uffff\1\u0120\2\uffff\1\u0121\3\uffff\1\u011f"+ + "\10\uffff\1\u0122", + "\1\u0126\1\uffff\1\u0126\5\uffff\1\u0124\2\uffff\1\u0125\3\uffff\1\u0123"+ + "\10\uffff\1\u0126", + "\1\u0126\1\uffff\1\u0126\5\uffff\1\u0124\2\uffff\1\u0125\3\uffff\1\u0123"+ + "\10\uffff\1\u0126", + "\1\u0126\1\uffff\1\u0126\5\uffff\1\u0124\2\uffff\1\u0125\3\uffff\1\u0123"+ + "\10\uffff\1\u0126", + "\1\u012a\1\uffff\1\u012a\5\uffff\1\u0128\2\uffff\1\u0129\3\uffff\1\u0127"+ + "\10\uffff\1\u012a", + "\1\u012a\1\uffff\1\u012a\5\uffff\1\u0128\2\uffff\1\u0129\3\uffff\1\u0127"+ + "\10\uffff\1\u012a", + "\1\u012a\1\uffff\1\u012a\5\uffff\1\u0128\2\uffff\1\u0129\3\uffff\1\u0127"+ + "\10\uffff\1\u012a", + "\1\u012e\1\uffff\1\u012e\5\uffff\1\u012c\2\uffff\1\u012d\3\uffff\1\u012b"+ + "\10\uffff\1\u012e", + "\1\u012e\1\uffff\1\u012e\5\uffff\1\u012c\2\uffff\1\u012d\3\uffff\1\u012b"+ + "\10\uffff\1\u012e", + "\1\u0132\1\uffff\1\u0132\5\uffff\1\u0130\2\uffff\1\u0131\3\uffff\1\u012f"+ + "\10\uffff\1\u0132", + "\1\u0132\1\uffff\1\u0132\5\uffff\1\u0130\2\uffff\1\u0131\3\uffff\1\u012f"+ + "\10\uffff\1\u0132", + "\1\u0132\1\uffff\1\u0132\5\uffff\1\u0130\2\uffff\1\u0131\3\uffff\1\u012f"+ + "\10\uffff\1\u0132", + "\1\u0136\1\uffff\1\u0136\5\uffff\1\u0134\2\uffff\1\u0135\3\uffff\1\u0133"+ + "\10\uffff\1\u0136", + "\1\u0136\1\uffff\1\u0136\5\uffff\1\u0134\2\uffff\1\u0135\3\uffff\1\u0133"+ + "\10\uffff\1\u0136", + "\1\u013a\1\uffff\1\u013a\5\uffff\1\u0138\2\uffff\1\u0139\3\uffff\1\u0137"+ + "\10\uffff\1\u013a", + "\1\u013a\1\uffff\1\u013a\5\uffff\1\u0138\2\uffff\1\u0139\3\uffff\1\u0137"+ + "\10\uffff\1\u013a", + "\1\u013a\1\uffff\1\u013a\5\uffff\1\u0138\2\uffff\1\u0139\3\uffff\1\u0137"+ + "\10\uffff\1\u013a", + "\1\u013a\1\uffff\1\u013a\5\uffff\1\u0138\2\uffff\1\u0139\3\uffff\1\u0137"+ + "\10\uffff\1\u013a", + "\1\u013a\1\uffff\1\u013a\5\uffff\1\u0138\2\uffff\1\u0139\3\uffff\1\u0137"+ + "\10\uffff\1\u013a", + "\1\u013a\1\uffff\1\u013a\5\uffff\1\u0138\2\uffff\1\u0139\3\uffff\1\u0137"+ + "\10\uffff\1\u013a", + "\1\u013a\1\uffff\1\u013a\5\uffff\1\u0138\2\uffff\1\u0139\3\uffff\1\u0137"+ + "\10\uffff\1\u013a", + "\1\u011e\1\uffff\1\u011e\5\uffff\1\u011c\2\uffff\1\u011d\3\uffff\1\u011b"+ + "\10\uffff\1\u011e", + "\1\u011e\1\uffff\1\u011e\5\uffff\1\u011c\2\uffff\1\u011d\3\uffff\1\u011b"+ + "\10\uffff\1\u011e", + "\1\u011e\1\uffff\1\u011e\10\uffff\1\u011d\14\uffff\1\u011e", + "\1\31\4\uffff\1\34\2\uffff\1\u0102\3\uffff\1\133\3\uffff\1\135\1\136"+ + "\6\uffff\1\137\1\140\1\uffff\1\u00b6\1\u0103\1\u0101\1\uffff\1\134\1"+ + "\uffff\1\32\1\u00b5\2\uffff\1\33\1\141", + "\1\u0122\1\uffff\1\u0122\5\uffff\1\u0120\2\uffff\1\u0121\3\uffff\1\u011f"+ + "\10\uffff\1\u0122", + "\1\u0122\1\uffff\1\u0122\5\uffff\1\u0120\2\uffff\1\u0121\3\uffff\1\u011f"+ + "\10\uffff\1\u0122", + "\1\u0122\1\uffff\1\u0122\10\uffff\1\u0121\14\uffff\1\u0122", + "\1\51\7\uffff\1\u0105\3\uffff\1\157\3\uffff\1\161\1\162\6\uffff\1\163"+ + "\1\164\1\uffff\1\u00c1\1\u0106\1\u0104\1\uffff\1\160\1\uffff\1\52\1\u00c0"+ + "\2\uffff\1\53\1\165", + "\1\u0126\1\uffff\1\u0126\5\uffff\1\u0124\2\uffff\1\u0125\3\uffff\1\u0123"+ + "\10\uffff\1\u0126", + "\1\u0126\1\uffff\1\u0126\5\uffff\1\u0124\2\uffff\1\u0125\3\uffff\1\u0123"+ + "\10\uffff\1\u0126", + "\1\u0126\1\uffff\1\u0126\10\uffff\1\u0125\14\uffff\1\u0126", + "\1\u00ce\7\uffff\1\u0108\3\uffff\1\u00c7\3\uffff\1\u00c9\1\u00ca\6\uffff"+ + "\1\u00cb\1\u00cc\1\uffff\1\u00c6\1\u0109\1\u0107\1\uffff\1\u00c8\1\uffff"+ + "\1\u00cf\1\u00c5\2\uffff\1\u00d0\1\u00cd", + "\1\u012a\1\uffff\1\u012a\5\uffff\1\u0128\2\uffff\1\u0129\3\uffff\1\u0127"+ + "\10\uffff\1\u012a", + "\1\u012a\1\uffff\1\u012a\5\uffff\1\u0128\2\uffff\1\u0129\3\uffff\1\u0127"+ + "\10\uffff\1\u012a", + "\1\u012a\1\uffff\1\u012a\10\uffff\1\u0129\14\uffff\1\u012a", + "\1\u00ce\7\uffff\1\u010b\3\uffff\1\u00c7\3\uffff\1\u00c9\1\u00ca\6\uffff"+ + "\1\u00cb\1\u00cc\1\uffff\1\u010e\1\u010c\1\u010a\1\uffff\1\u00c8\1\uffff"+ + "\1\u00cf\1\u010d\2\uffff\1\u00d0\1\u00cd", + "\1\u012e\1\uffff\1\u012e\5\uffff\1\u012c\2\uffff\1\u012d\3\uffff\1\u012b"+ + "\10\uffff\1\u012e", + "\1\u012e\1\uffff\1\u012e\5\uffff\1\u012c\2\uffff\1\u012d\3\uffff\1\u012b"+ + "\10\uffff\1\u012e", + "\1\u012e\1\uffff\1\u012e\10\uffff\1\u012d\14\uffff\1\u012e", + "\1\u00ce\7\uffff\1\u013c\3\uffff\1\u00c7\3\uffff\1\u00c9\1\u00ca\6\uffff"+ + "\1\u00cb\1\u00cc\1\uffff\1\u010e\1\u013d\1\u013b\1\uffff\1\u00c8\1\uffff"+ + "\1\u00cf\1\u010d\2\uffff\1\u00d0\1\u00cd", + "\1\u0132\1\uffff\1\u0132\5\uffff\1\u0130\2\uffff\1\u0131\3\uffff\1\u012f"+ + "\10\uffff\1\u0132", + "\1\u0132\1\uffff\1\u0132\5\uffff\1\u0130\2\uffff\1\u0131\3\uffff\1\u012f"+ + "\10\uffff\1\u0132", + "\1\u0132\1\uffff\1\u0132\10\uffff\1\u0131\14\uffff\1\u0132", + "\1\u00ce\7\uffff\1\u0110\3\uffff\1\u0114\3\uffff\1\u0116\1\u0117\6\uffff"+ + "\1\u0118\1\u0119\1\uffff\1\u0113\1\u0111\1\u010f\1\uffff\1\u0115\1\uffff"+ + "\1\u00cf\1\u0112\2\uffff\1\u00d0\1\u011a", + "\1\u0136\1\uffff\1\u0136\5\uffff\1\u0134\2\uffff\1\u0135\3\uffff\1\u0133"+ + "\10\uffff\1\u0136", + "\1\u0136\1\uffff\1\u0136\5\uffff\1\u0134\2\uffff\1\u0135\3\uffff\1\u0133"+ + "\10\uffff\1\u0136", + "\1\u0136\1\uffff\1\u0136\10\uffff\1\u0135\14\uffff\1\u0136", + "\1\u00ce\7\uffff\1\u013f\3\uffff\1\u0114\3\uffff\1\u0116\1\u0117\6\uffff"+ + "\1\u0118\1\u0119\1\uffff\1\u0113\1\u0140\1\u013e\1\uffff\1\u0115\1\uffff"+ + "\1\u00cf\1\u0112\2\uffff\1\u00d0\1\u011a", + "\1\u013a\1\uffff\1\u013a\5\uffff\1\u0138\2\uffff\1\u0139\3\uffff\1\u0137"+ + "\10\uffff\1\u013a", + "\1\u013a\1\uffff\1\u013a\5\uffff\1\u0138\2\uffff\1\u0139\3\uffff\1\u0137"+ + "\10\uffff\1\u013a", + "\1\u013a\1\uffff\1\u013a\10\uffff\1\u0139\14\uffff\1\u013a", + "\1\u00ce\7\uffff\1\u0142\3\uffff\1\u0114\3\uffff\1\u0116\1\u0117\6\uffff"+ + "\1\u0118\1\u0119\1\uffff\1\u0145\1\u0143\1\u0141\1\uffff\1\u0115\1\uffff"+ + "\1\u00cf\1\u0144\2\uffff\1\u00d0\1\u011a", + "\1\u0149\1\uffff\1\u0149\5\uffff\1\u0147\2\uffff\1\u0148\3\uffff\1\u0146"+ + "\10\uffff\1\u0149", + "\1\u0149\1\uffff\1\u0149\5\uffff\1\u0147\2\uffff\1\u0148\3\uffff\1\u0146"+ + "\10\uffff\1\u0149", + "\1\u0149\1\uffff\1\u0149\5\uffff\1\u0147\2\uffff\1\u0148\3\uffff\1\u0146"+ + "\10\uffff\1\u0149", + "\1\u014d\1\uffff\1\u014d\5\uffff\1\u014b\2\uffff\1\u014c\3\uffff\1\u014a"+ + "\10\uffff\1\u014d", + "\1\u014d\1\uffff\1\u014d\5\uffff\1\u014b\2\uffff\1\u014c\3\uffff\1\u014a"+ + "\10\uffff\1\u014d", + "\1\u014d\1\uffff\1\u014d\5\uffff\1\u014b\2\uffff\1\u014c\3\uffff\1\u014a"+ + "\10\uffff\1\u014d", + "\1\u0151\1\uffff\1\u0151\5\uffff\1\u014f\2\uffff\1\u0150\3\uffff\1\u014e"+ + "\10\uffff\1\u0151", + "\1\u0151\1\uffff\1\u0151\5\uffff\1\u014f\2\uffff\1\u0150\3\uffff\1\u014e"+ + "\10\uffff\1\u0151", + "\1\u0151\1\uffff\1\u0151\5\uffff\1\u014f\2\uffff\1\u0150\3\uffff\1\u014e"+ + "\10\uffff\1\u0151", + "\1\u0155\1\uffff\1\u0155\5\uffff\1\u0153\2\uffff\1\u0154\3\uffff\1\u0152"+ + "\10\uffff\1\u0155", + "\1\u0155\1\uffff\1\u0155\5\uffff\1\u0153\2\uffff\1\u0154\3\uffff\1\u0152"+ + "\10\uffff\1\u0155", + "\1\u0149\1\uffff\1\u0149\5\uffff\1\u0147\2\uffff\1\u0148\3\uffff\1\u0146"+ + "\10\uffff\1\u0149", + "\1\u0149\1\uffff\1\u0149\5\uffff\1\u0147\2\uffff\1\u0148\3\uffff\1\u0146"+ + "\10\uffff\1\u0149", + "\1\u0149\1\uffff\1\u0149\10\uffff\1\u0148\14\uffff\1\u0149", + "\1\u00ce\7\uffff\1\u013c\3\uffff\1\u00c7\3\uffff\1\u00c9\1\u00ca\6\uffff"+ + "\1\u00cb\1\u00cc\1\uffff\1\u010e\1\u013d\1\u013b\1\uffff\1\u00c8\1\uffff"+ + "\1\u00cf\1\u010d\2\uffff\1\u00d0\1\u00cd", + "\1\u014d\1\uffff\1\u014d\5\uffff\1\u014b\2\uffff\1\u014c\3\uffff\1\u014a"+ + "\10\uffff\1\u014d", + "\1\u014d\1\uffff\1\u014d\5\uffff\1\u014b\2\uffff\1\u014c\3\uffff\1\u014a"+ + "\10\uffff\1\u014d", + "\1\u014d\1\uffff\1\u014d\10\uffff\1\u014c\14\uffff\1\u014d", + "\1\u00ce\7\uffff\1\u013f\3\uffff\1\u0114\3\uffff\1\u0116\1\u0117\6\uffff"+ + "\1\u0118\1\u0119\1\uffff\1\u0113\1\u0140\1\u013e\1\uffff\1\u0115\1\uffff"+ + "\1\u00cf\1\u0112\2\uffff\1\u00d0\1\u011a", + "\1\u0151\1\uffff\1\u0151\5\uffff\1\u014f\2\uffff\1\u0150\3\uffff\1\u014e"+ + "\10\uffff\1\u0151", + "\1\u0151\1\uffff\1\u0151\5\uffff\1\u014f\2\uffff\1\u0150\3\uffff\1\u014e"+ + "\10\uffff\1\u0151", + "\1\u0151\1\uffff\1\u0151\10\uffff\1\u0150\14\uffff\1\u0151", + "\1\u00ce\7\uffff\1\u0142\3\uffff\1\u0114\3\uffff\1\u0116\1\u0117\6\uffff"+ + "\1\u0118\1\u0119\1\uffff\1\u0145\1\u0143\1\u0141\1\uffff\1\u0115\1\uffff"+ + "\1\u00cf\1\u0144\2\uffff\1\u00d0\1\u011a", + "\1\u0155\1\uffff\1\u0155\5\uffff\1\u0153\2\uffff\1\u0154\3\uffff\1\u0152"+ + "\10\uffff\1\u0155", + "\1\u0155\1\uffff\1\u0155\5\uffff\1\u0153\2\uffff\1\u0154\3\uffff\1\u0152"+ + "\10\uffff\1\u0155", + "\1\u0155\1\uffff\1\u0155\10\uffff\1\u0154\14\uffff\1\u0155", + "\1\u00ce\7\uffff\1\u0157\3\uffff\1\u0114\3\uffff\1\u0116\1\u0117\6\uffff"+ + "\1\u0118\1\u0119\1\uffff\1\u0145\1\u0158\1\u0156\1\uffff\1\u0115\1\uffff"+ + "\1\u00cf\1\u0144\2\uffff\1\u00d0\1\u011a", + "\1\u015c\1\uffff\1\u015c\5\uffff\1\u015a\2\uffff\1\u015b\3\uffff\1\u0159"+ + "\10\uffff\1\u015c", + "\1\u015c\1\uffff\1\u015c\5\uffff\1\u015a\2\uffff\1\u015b\3\uffff\1\u0159"+ + "\10\uffff\1\u015c", + "\1\u015c\1\uffff\1\u015c\5\uffff\1\u015a\2\uffff\1\u015b\3\uffff\1\u0159"+ + "\10\uffff\1\u015c", + "\1\u015c\1\uffff\1\u015c\5\uffff\1\u015a\2\uffff\1\u015b\3\uffff\1\u0159"+ + "\10\uffff\1\u015c", + "\1\u015c\1\uffff\1\u015c\5\uffff\1\u015a\2\uffff\1\u015b\3\uffff\1\u0159"+ + "\10\uffff\1\u015c", + "\1\u015c\1\uffff\1\u015c\10\uffff\1\u015b\14\uffff\1\u015c", + "\1\u00ce\7\uffff\1\u0157\3\uffff\1\u0114\3\uffff\1\u0116\1\u0117\6\uffff"+ + "\1\u0118\1\u0119\1\uffff\1\u0145\1\u0158\1\u0156\1\uffff\1\u0115\1\uffff"+ + "\1\u00cf\1\u0144\2\uffff\1\u00d0\1\u011a" + }; + + static final short[] DFA25_eot = DFA.unpackEncodedString(DFA25_eotS); + static final short[] DFA25_eof = DFA.unpackEncodedString(DFA25_eofS); + static final char[] DFA25_min = DFA.unpackEncodedStringToUnsignedChars(DFA25_minS); + static final char[] DFA25_max = DFA.unpackEncodedStringToUnsignedChars(DFA25_maxS); + static final short[] DFA25_accept = DFA.unpackEncodedString(DFA25_acceptS); + static final short[] DFA25_special = DFA.unpackEncodedString(DFA25_specialS); + static final short[][] DFA25_transition; + + static { + int numStates = DFA25_transitionS.length; + DFA25_transition = new short[numStates][]; + for (int i=0; i + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.BinaryTree; + +import java.util.*; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class BinaryTree { + + /* Tables for storing nodes that are not root. */ + HashMap uniqueNodeTbl; + Vector NodeIdxTbl; + + /* Tables for storing root nodes and their indices. */ + HashMap uniqueRootNodeTbl; + Vector rootNodeIdxTbl; + + /* Size restricted fast lookup */ + HashMap lastAccessedTbl; + LinkedList lastAccessedIdxList; + + + public BinaryTree() { + this.uniqueNodeTbl = new HashMap(); + this.NodeIdxTbl = new Vector(100); + + this.uniqueRootNodeTbl = new HashMap(); + this.rootNodeIdxTbl = new Vector(100); + + lastAccessedTbl = new HashMap(); + lastAccessedIdxList = new LinkedList(); + } + + /* + * Build a binary tree for IdxArray. + * Return the the literal of the root node. + */ + public int add(int[] IdxArray) { + if(IdxArray == null) + return -1; + + //System.out.println("add " + Arrays.toString(IdxArray)); + int[] nodeLitArray = IdxArray; + int[] attributeArray = new int[IdxArray.length]; + + for (int i = 0; i < IdxArray.length; i++) { + attributeArray[i] = 1; + } + + while (nodeLitArray.length > 1) { + int lastSlot = nodeLitArray[nodeLitArray.length - 1]; + int lastAttribute = attributeArray[attributeArray.length-1]; + + boolean arrayLenOdd = true; + if ((nodeLitArray.length & 1) == 0) + arrayLenOdd = false; + + int pairCnt = nodeLitArray.length >> 1; + + int[] newnodeLitArray = null; + int[] newattributeArray = null; + + if (arrayLenOdd == true) { + newnodeLitArray = new int[pairCnt + 1]; + newattributeArray = new int[pairCnt + 1]; + } else { + newnodeLitArray = new int[pairCnt]; + newattributeArray = new int[pairCnt]; + } + + for (int i = 0; i < pairCnt; i++) { + Node newNode = new Node(); + newNode.setLeft(nodeLitArray[i*2]); + newNode.setRight(nodeLitArray[i*2 + 1]); + char terminal = 0x00; + if(attributeArray[i*2]==1) { + terminal = (char)(terminal | 0xF0); + } + if(attributeArray[i*2+1]==1) { + terminal = (char)(terminal | 0x0F); + } + newNode.setTerminal(terminal); + + /* If nodeLitArray has more than 2 literals, newNode, which is not a root node, is added by calling addNode(). + * Otherwise, newNode is a root node, and added by calling addRootNode(). */ + int newNodeLit = nodeLitArray.length > 2 ? this.addNode(newNode) : this.addRootNode(newNode); + newnodeLitArray[i] = newNodeLit; + newattributeArray[i] = 0; + } + + if (arrayLenOdd == true) { + newnodeLitArray[pairCnt] = lastSlot; + newattributeArray[pairCnt] = lastAttribute; + } + + nodeLitArray = newnodeLitArray; + attributeArray = newattributeArray; + } + //System.out.println("add node lit = " + nodeLitArray[0] + "\n"); + //System.out.println("added vec = " + Arrays.toString(this.toIntArray(nodeLitArray[0])) + "\n"); + int rootLit = nodeLitArray[0]; + + if(this.lastAccessedTbl.containsKey(rootLit) == false) { + if(this.lastAccessedIdxList.size() > 1000000) { + int oldestIdx = this.lastAccessedIdxList.removeFirst(); + this.lastAccessedTbl.remove(oldestIdx); + } + this.lastAccessedIdxList.addLast(rootLit); + this.lastAccessedTbl.put(rootLit, IdxArray); + } + + return rootLit; + } + + public boolean contains(int[] IdxArray) { + //System.out.println("check " + Arrays.toString(IdxArray)); + int[] nodeLitArray = IdxArray; + int[] attributeArray = new int[IdxArray.length]; + + for (int i = 0; i < IdxArray.length; i++) { + attributeArray[i] = 1; + } + + while (nodeLitArray.length > 1) { + int lastSlot = nodeLitArray[nodeLitArray.length - 1]; + int lastAttribute = attributeArray[attributeArray.length-1]; + + boolean arrayLenOdd = true; + if ((nodeLitArray.length & 1) == 0) + arrayLenOdd = false; + + int pairCnt = nodeLitArray.length >> 1; + + int[] newnodeLitArray = null; + int[] newattributeArray = null; + + if (arrayLenOdd == true) { + newnodeLitArray = new int[pairCnt + 1]; + newattributeArray = new int[pairCnt + 1]; + } else { + newnodeLitArray = new int[pairCnt]; + newattributeArray = new int[pairCnt]; + } + + for (int i = 0; i < pairCnt; i++) { + Node newNode = new Node(); + newNode.setLeft(nodeLitArray[i*2]); + newNode.setRight(nodeLitArray[i*2 + 1]); + char terminal = 0x00; + if(attributeArray[i*2]==1) + terminal = (char)(terminal | 0xF0); + if(attributeArray[i*2+1]==1) + terminal = (char)(terminal | 0x0F); + newNode.setTerminal(terminal); + int newNodeLit = pairCnt > 1 ? this.getNodeLit(newNode) : this.getRootNodeLit(newNode); + if(newNodeLit == -1) { + return false; + } + newnodeLitArray[i] = newNodeLit; + newattributeArray[i] = 0; + } + + if (arrayLenOdd == true) { + newnodeLitArray[pairCnt] = lastSlot; + newattributeArray[pairCnt] = lastAttribute; + } + + nodeLitArray = newnodeLitArray; + attributeArray = newattributeArray; + } + return nodeLitArray[0] == -1 ? false : true; + + } + + public int[] toIntArray(int nodeLit) { + + int[] tmp = this.lastAccessedTbl.get(nodeLit); + if(tmp != null) + return tmp; + + boolean flipped = ((nodeLit & 1) == 1); + + Node rootNode = this.getRootNode(nodeLit); + if(rootNode==null) + return null; + + LinkedList IntList = rootNode.toIntArray(this, flipped); + + int[] result = new int[IntList.size()]; + int pos = 0; + while(IntList.size() > 0) { + result[pos] = IntList.removeFirst(); + pos++; + } + return result; + } + + private int addNode(Node node) { + int nodeLit = this.getNodeLit(node); + + if (nodeLit != -1) + return nodeLit; + + int idx = this.uniqueNodeTbl.size()+1; + node.setIndex(idx); + this.uniqueNodeTbl.put(node, node); + + if(idx >= this.NodeIdxTbl.size()) { + this.NodeIdxTbl.setSize(this.NodeIdxTbl.size() + 100); + } + this.NodeIdxTbl.setElementAt(node, idx); + return (idx << 1); + } + + private int addRootNode(Node node) { + int nodeLit = this.getRootNodeLit(node); + + if (nodeLit != -1) + return nodeLit; + + int idx = this.uniqueRootNodeTbl.size()+1; + node.setIndex(idx); + this.uniqueRootNodeTbl.put(node, node); + + if(idx >= this.rootNodeIdxTbl.size()) { + this.rootNodeIdxTbl.setSize(this.rootNodeIdxTbl.size() + 100); + } + this.rootNodeIdxTbl.setElementAt(node, idx); + return (idx << 1); + } + + public Node getNode(int nodeLit) { + int nodeIdx = nodeLit >> 1; + return this.NodeIdxTbl.get(nodeIdx); + } + + public Node getRootNode(int nodeLit) { + int nodeIdx = nodeLit >> 1; + return this.rootNodeIdxTbl.get(nodeIdx); + } + + /* + * Check if 'node' exists in the node table. If yes, return the node + * literal. If the node complement exists, return its literal as well. + * Otherwise, return -1. + */ + public int getNodeLit(Node node) { + Node cachedNode = this.uniqueNodeTbl.get(node); + + if (cachedNode != null) { + int idx = cachedNode.getIndex(); + return idx << 1; + } + + Node flipNode = node.flip(); + Node cachedFlipNode = this.uniqueNodeTbl.get(flipNode); + if (cachedFlipNode != null) { + int idx = cachedFlipNode.getIndex(); + return (idx << 1) + 1; + } + + return -1; + } + + public int getRootNodeLit(Node node) { + Node cachedNode = this.uniqueRootNodeTbl.get(node); + + if (cachedNode != null) { + int idx = cachedNode.getIndex(); + return idx << 1; + } + + Node flipNode = node.flip(); + Node cachedFlipNode = this.uniqueRootNodeTbl.get(flipNode); + if (cachedFlipNode != null) { + int idx = cachedFlipNode.getIndex(); + return (idx << 1) + 1; + } + + return -1; + } + + public int nodeCount() { + return this.uniqueNodeTbl.size(); + } + + public int elementCount() { + return this.uniqueRootNodeTbl.size(); + } + + @Override + public String toString() { + return "BinaryTree [uniqueNodeTbl=" + this.NodeIdxTbl + "]"; + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/BinaryTree/Node.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/BinaryTree/Node.java new file mode 100644 index 000000000..0afa3acb9 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/BinaryTree/Node.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.BinaryTree; + +import java.util.*; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Node { + + int LeftLit; + + int RightLit; + + int index; + + char terminal; + + public Node() { + this.LeftLit = -1; + this.RightLit = -1; + this.index = -1; + this.terminal = 0x11; + } + + public void setLeft(int lit) { + this.LeftLit = lit; + } + + public void setRight(int lit) { + this.RightLit = lit; + } + + public int getLeft() { + return this.LeftLit; + } + + public int getRight() { + return this.RightLit; + } + + public void setIndex(int idx) { + this.index = idx; + } + + public int getIndex() { + return this.index; + } + + public void setTerminal(char terminal) { + this.terminal = terminal; + } + + public Node flip() { + Node flipNode = new Node(); + flipNode.LeftLit = this.RightLit; + flipNode.RightLit = this.LeftLit; + if(this.terminal==0xF0) + flipNode.terminal = 0x0F; + else if(this.terminal==0x0F) + flipNode.terminal = 0xF0; + else if(this.terminal!=0xFF && this.terminal!=0x00) { + System.out.println("*** Wrong value for binary tree Node.terminal " + this.terminal); + System.exit(0); + } + return flipNode; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + LeftLit; + result = prime * result + RightLit; + result = prime * result + terminal; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Node other = (Node) obj; + if (LeftLit != other.LeftLit) + return false; + if (RightLit != other.RightLit) + return false; + if (terminal != other.terminal) + return false; + return true; + } + + public char isTerminal() { + return this.terminal; + } + + public LinkedList toIntArray(BinaryTree tree, boolean flipped) { + int lLit = this.LeftLit; + int rLit = this.RightLit; + if(flipped==true) { + lLit = this.RightLit; + rLit = this.LeftLit; + } + + LinkedList lIntList = null; + LinkedList rIntList = null; + if(this.terminal != 0xFF) { + if((this.terminal & 0xF0) == 0x00) { // left is not a terminal + Node leftNode = tree.getNode(lLit); + boolean leftFlipped = ((lLit & 1) == 1); + lIntList = leftNode.toIntArray(tree, leftFlipped); + if(this.terminal==0x0F) { + lIntList.addLast(rLit); + return lIntList; + } + } + + if((this.terminal & 0x0F) == 0x00) { // right is not a terminal + Node rightNode = tree.getNode(rLit); + boolean rightFlipped = ((rLit & 1) == 1); + rIntList = rightNode.toIntArray(tree, rightFlipped); + if(this.terminal==0xF0) { + rIntList.addLast(lLit); + return rIntList; + } + } + + // Case: this.terminal==0x00 + while(rIntList!=null && lIntList != null && rIntList.size() > 0) { + int number = rIntList.removeFirst(); + lIntList.addLast(number); + } + return lIntList; + } + LinkedList result = new LinkedList(); + result.addLast(lLit); + result.addLast(rLit); + return result; + } + + + + @Override + public String toString() { + String terminalStr = ""; + if(this.terminal==0xF0) + terminalStr = "0xF0"; + else if(this.terminal==0x0F) + terminalStr = "0x0F"; + else if(this.terminal==0xFF) + terminalStr = "0xFF"; + else if(this.terminal==0x00) + terminalStr = "0x00"; + else + terminalStr = "xxxx"; + + return "Node [Left=" + LeftLit + ", Right=" + RightLit + ", index=" + index + ", terminal=" + terminalStr + "]"; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/MDT.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/MDT.java new file mode 100644 index 000000000..66f35267f --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/MDT.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.MDD; + +import java.util.*; + +import edu.utah.ece.async.lema.verification.platu.stategraph.*; + +/** + * This data structure cannot be used as stack as it allows node sharing. + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class MDT { + static mdtNode terminal = new mdtNode(); + + private mdtNode root; + //private int stateCount; + //private int peakNodes; + int height; + int Size; + + /* + * Initialize MDD with the number of modules in the design model. + */ + public MDT(int levels) { + root = new mdtNode(); + //stateCount = 0; + height = levels; + //peakNodes = 0; + } + + public void push(State[] curIdxArray) { + root.push(curIdxArray, 0); + this.Size++; + } + + public State[] pop() { + this.Size--; + State[] results = new State[this.height]; + return root.pop(results); + } + + public Stack popList() { + this.Size--; + State[] results = new State[this.height]; + return root.popList(results); + } + +// public State[] peek() { +// return root.peek(0); +// } + + public boolean contains(State[] stateArray) { + return root.contains(stateArray, 0); + } + + public boolean empty() { + return root.empty(); + } + + public int size() { + return this.Size; + } + + public int nodeCnt() { + return root.nodeCnt(); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/Mdd.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/Mdd.java new file mode 100644 index 000000000..47b9a8299 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/Mdd.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.MDD; + +import java.util.*; + +import edu.utah.ece.async.lema.verification.platu.stategraph.*; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Mdd { + static mddNode terminal = new mddNode(); + + //private int stateCount; + private HashMap[] nodeTbl; + private HashMap>[] localFirings; + private int peakNodes; + int height; + + /* + * Initialize MDD with the number of modules in the design model. + */ + @SuppressWarnings("unchecked") + public Mdd(int numMods) { + Mdd.terminal.level = numMods; + //stateCount = 0; + height = numMods; + nodeTbl = new HashMap[height]; + localFirings = new HashMap[height+1]; + for(int i = 0; i < this.height; i++) { + nodeTbl[i] = new HashMap(); + localFirings[i] = new HashMap>(); + } + + peakNodes = 0; + } + + public static mddNode newNode() { + return new mddNode(0); + } + + /* + * Return a MDD node that is the root of MDD representing the union of states encoded in MDD 'target' and MDD 'source' + */ + public mddNode union(mddNode target, mddNode source) { + HashMap> unionCache = new HashMap>(); + mddNode unionResult = target.union(source, nodeTbl, unionCache); + return unionResult; + } + + + + /* + * create a MDD for stateArray. The nodes in the created MDD are added into the nodeTbl. + */ + public boolean add(mddNode target, int[] idxArray) { + target = target.add(idxArray, nodeTbl, 20); + + int curNodes = 0; + for(int i = 0; i < this.height; i++) + curNodes += nodeTbl[i].size(); + + if(curNodes > peakNodes) + peakNodes = curNodes; + + //stateCount++; + return true; + } + + public boolean add(mddNode target, int[] idxArray, boolean sharing) { + if(sharing==true) + target.add(idxArray, nodeTbl, 20); + else + target.add(idxArray); + + return true; + } + + + public void compress(mddNode target) { + target.compress(nodeTbl); + } + + + public mddNode doLocalFirings(StateGraph[] curLpnArray, State[] curStateArray, mddNode reachSet) { + mddNode result = Mdd.newNode(); + @SuppressWarnings("unchecked") + LinkedList[] nextSetArray = (new LinkedList[curLpnArray.length]); + for(int i = 0; i < curLpnArray.length; i++) + nextSetArray[i] = new LinkedList(); + + // Do firings of local LPN transition. + mddNode newResult = result.doLocalFirings(curLpnArray, curStateArray, nextSetArray, reachSet, nodeTbl); + + if(newResult == result) + return result; + this.remove(result); + return newResult; + } + + + public void remove(mddNode target) { + target.remove(nodeTbl); + if(target.refCount<=0) + nodeTbl[0].remove(target); + } + + /* + * Check if there is a path in MDD that corresponds to stateArray. Return true if so. + */ + public static boolean contains(mddNode target, int[] idxArray) { + if(target == null) + return false; + return target.contains(idxArray)==Mdd.terminal; + } + + public int[] next(mddNode curNode) { + if(curNode == null) + return null; + return curNode.next(height); + } + + public int[] next(mddNode curNode, int[] curIdxArray) { + if(curIdxArray == null) + return curNode.next(height); + return curNode.next(height, curIdxArray); + } + + public static double numberOfStates(mddNode target) { + HashSet uniqueNodes = new HashSet(); + double paths = target.pathCount(uniqueNodes); + return paths; + } + + public int nodeCnt() { + int curNodes = 0; + for(int i = 0; i < this.height; i++) + curNodes += nodeTbl[i].size(); + return curNodes; + } + + public HashMap>[] getLocalFiringTbl() { + return localFirings; + } + + /* + * Returns the largest number of MDD nodes created when this MDD is live. + */ + public int peakNodeCnt() { + return peakNodes; + } + + public void check() + { + for(int i = 0; i < this.height; i++) { + Set entries = nodeTbl[i].entrySet(); + Iterator it = entries.iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + mddNode tmp = (mddNode)entry.getKey(); + System.out.println("nodeTbl@" + i + " >>> " + tmp + ": level = " + tmp.level + ", refCount = " + tmp.refCount); + //+ ", " + tmp.nodeMapSize); + } + } + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/mddNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/mddNode.java new file mode 100644 index 000000000..412500fdf --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/mddNode.java @@ -0,0 +1,824 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.MDD; + +import java.util.*; + +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class mddNode { + static int blockSize = 8; + static int numBlocks = 16; + static int blockIdxMask = 15; + static int arrayIdxoffset = 4; + + int level; + private mddNode[][] nodeMap; + private int[] blkHashVal; + int refCount; + int hashVal; + int nodeMapSize; + int maxArrayBound; + + public mddNode() { + this.reset(); + } + + public mddNode(int thisLevel) { + this.reset(); + level = thisLevel; + } + + private void reset() { + level = -1; + nodeMap = new mddNode[numBlocks][blockSize]; + this.blkHashVal = new int[numBlocks]; + for(int i = 0; i < numBlocks; i++){ + this.nodeMap[i] = null; + this.blkHashVal[i] = 0; + } + refCount = 0; + hashVal = 0; + nodeMapSize = 0; + maxArrayBound = -1; + } + + + private mddNode split() { + mddNode copy = new mddNode(); + copy.level = this.level; + for(int blkIter = 0; blkIter < mddNode.numBlocks; blkIter++) { + if(this.nodeMap[blkIter] == null) + continue; + for(int arrayIter = 0; arrayIter < this.nodeMap[blkIter].length; arrayIter++) { + mddNode succ = this.getSucc(blkIter, arrayIter); + if(succ != null) + copy.addSucc(blkIter, arrayIter, succ); + } + copy.blkHashVal[blkIter] = this.blkHashVal[blkIter]; + } + + copy.refCount = 0; + copy.hashVal = this.hashVal; + return copy; + } + + /** + * Add an integer tuple into MDD root at this node. + * Isomorphic nodes are not shared. + * + * @param idxArray + * @return null if input idxArray is added into the MDD, root node otherwise. + */ + public mddNode add(int[] idxArray) { + if(this.level == -1) { + System.out.println("level is not right 1"); + System.exit(0); + } + + int curIdx = idxArray[this.level]; + int stateIdx = curIdx; + int blockIdx = stateIdx & mddNode.blockIdxMask; + int arrayIdx = stateIdx >> mddNode.arrayIdxoffset; + + mddNode nextNode = this.getSucc(blockIdx, arrayIdx); + + if(nextNode == null) { + if(this.level == idxArray.length-1) { + this.addSucc(blockIdx, arrayIdx, Mdd.terminal); + this.blkHashVal[blockIdx] = Integer.rotateLeft(Arrays.hashCode(this.nodeMap[blockIdx]), this.level); + this.hashVal = 0; + return null; + } + nextNode = new mddNode(); + nextNode.level = this.level + 1; + nextNode.add(idxArray); + this.addSucc(blockIdx, arrayIdx, nextNode); + this.blkHashVal[blockIdx] = Integer.rotateLeft(Arrays.hashCode(this.nodeMap[blockIdx]), this.level); + this.hashVal = 0; + + return null; + } + if(nextNode == Mdd.terminal) + return this; + else if(nextNode.add(idxArray)==null) + return null; + return this; + } + + public mddNode add(int[] idxArray, HashMap[] nodeTbl, int shrLevel) { + if(this.level == -1) { + System.out.println("level is not right 1"); + System.exit(0); + } + + int curIdx = idxArray[this.level]; + int stateIdx = curIdx; + int blockIdx = stateIdx & mddNode.blockIdxMask; + int arrayIdx = stateIdx >> mddNode.arrayIdxoffset; + + mddNode nextNode = this.getSucc(blockIdx, arrayIdx); + + if(nextNode == null) { + if(this.level == idxArray.length-1) { + nodeTbl[this.level].remove(this); + this.addSucc(blockIdx, arrayIdx, Mdd.terminal); + this.blkHashVal[blockIdx] = Integer.rotateLeft(Arrays.hashCode(this.nodeMap[blockIdx]), this.level); + this.hashVal = 0; + + mddNode newThisNode = nodeTbl[this.level].get(this); + if(newThisNode != null) { + return newThisNode; + } + + nodeTbl[this.level].put(this, this); + return this; + } + nextNode = new mddNode(); + nextNode.level = this.level + 1; + + mddNode newNextNode = nextNode.add(idxArray, nodeTbl, shrLevel); + if(newNextNode != nextNode) + nextNode = newNextNode; + nextNode.refCount++; + + if(level < shrLevel) + nodeTbl[this.level].remove(this); + + this.addSucc(blockIdx, arrayIdx, nextNode); + this.blkHashVal[blockIdx] = Integer.rotateLeft(Arrays.hashCode(this.nodeMap[blockIdx]), this.level); + this.hashVal = 0; + + if(level < shrLevel) { + mddNode newThis = nodeTbl[this.level].get(this); + if (newThis != null) { + for(int blkIter = 0; blkIter < mddNode.numBlocks; blkIter++) { + if(this.nodeMap[blkIter] == null) + continue; + for(int arrayIter = 0; arrayIter < this.nodeMap[blkIter].length; arrayIter++) + if(this.nodeMap[blkIter][arrayIter] != null) + this.nodeMap[blkIter][arrayIter].refCount--; + } + + return newThis; + } + + nodeTbl[this.level].put(this, this); + } + return this; + } + else if(nextNode == Mdd.terminal) { + //System.out.println("mddNode: should not reach here. Abort!"); + //System.exit(0); + return Mdd.terminal; + } + else { + mddNode newNextNode = nextNode; + if(nextNode.refCount > 1) { + newNextNode = nextNode.split();//new mddNode(nextNode); + nextNode.refCount--; +// for(int blkIter = 0; blkIter < mddNode.numBlocks; blkIter++) { +// if(nextNode.nodeMap[blkIter] == null) +// continue; +// +// for(int arrayIter = 0; arrayIter < nextNode.nodeMap[blkIter].length; arrayIter++) +// if(nextNode.nodeMap[blkIter][arrayIter] != null) +// nextNode.nodeMap[blkIter][arrayIter].refCount++; +// } + + mddNode newNextNode_1 = newNextNode.add(idxArray, nodeTbl, shrLevel); + + if (newNextNode_1 != newNextNode) + newNextNode = newNextNode_1; + } + else { + newNextNode = nextNode.add(idxArray, nodeTbl, shrLevel); + + // if no next node is splitted and the next node does not have equivalent, + // do nothing further. + if(newNextNode == nextNode) + return this; + + nextNode.refCount--; + for(int blkIter = 0; blkIter < mddNode.numBlocks; blkIter++) { + if(nextNode.nodeMap[blkIter] == null) + continue; + + for(int arrayIter = 0; arrayIter < nextNode.nodeMap[blkIter].length; arrayIter++) + if(nextNode.nodeMap[blkIter][arrayIter] != null) + nextNode.nodeMap[blkIter][arrayIter].refCount++; + } + } + + if(level < shrLevel) + nodeTbl[this.level].remove(this); + + newNextNode.refCount++; + this.addSucc(blockIdx, arrayIdx, newNextNode); + this.blkHashVal[blockIdx] = Integer.rotateLeft(Arrays.hashCode(this.nodeMap[blockIdx]), this.level); + this.hashVal = 0; + + if(level < shrLevel) { + mddNode newThis = nodeTbl[this.level].get(this); + if (newThis != null) { + for(int blkIter = 0; blkIter < mddNode.numBlocks; blkIter++) { + if(this.nodeMap[blkIter] == null) + continue; + + for(int arrayIter = 0; arrayIter < this.nodeMap[blkIter].length; arrayIter++) + if(this.nodeMap[blkIter][arrayIter] != null) + this.nodeMap[blkIter][arrayIter].refCount--; + } + + return newThis; + } + + nodeTbl[this.level].put(this, this); + } + return this; + } + } + + public static int numCalls = 0; + public static int cacheNodes = 0; + public static int splits_level1 = 0; + public static int splits_level2 = 0; + public static int splits_level3 = 0; + + public mddNode union(final mddNode other, HashMap[] nodeTbl, HashMap> unionCache) { + numCalls++; + + mddNode thisCopy = this.split(); + + for(int blkIter = 0; blkIter < mddNode.numBlocks; blkIter++) { + if(other.nodeMap[blkIter] == null) + continue; + + for(int arrayIter = 0; arrayIter < other.nodeMap[blkIter].length; arrayIter++) { + mddNode thisSucc = this.getSucc(blkIter, arrayIter); + mddNode otherSucc = other.getSucc(blkIter, arrayIter); + + if(otherSucc == null) + continue; + + if(thisSucc == null) { + thisCopy.addSucc(blkIter, arrayIter, otherSucc); + continue; + } + + // When successors are terminals, return. + if(thisSucc == Mdd.terminal || otherSucc == Mdd.terminal) + continue; + + if(thisSucc==otherSucc || otherSucc.subSet(thisSucc) == true) + continue; + + mddNode succCached = null; + HashMap second = unionCache.get(thisSucc); + if(second != null) { + succCached = second.get(otherSucc); + } + + if(succCached == null) { + mddNode succUnion = thisSucc.union(otherSucc, nodeTbl, unionCache); + + // Add newSucc into the cache to avoid call union(thisSuccOriginal, otherSucc) again. + HashMap secondCache = unionCache.get(thisSucc); + cacheNodes++; + if(secondCache == null) { + secondCache = new HashMap(); + secondCache.put(otherSucc, succUnion); + unionCache.put(thisSucc, secondCache); + } + else + secondCache.put(otherSucc, succUnion); + + succCached = succUnion; + } + thisSucc.remove(nodeTbl); + thisCopy.addSucc(blkIter, arrayIter, succCached); + } + } + + mddNode result = nodeTbl[thisCopy.level].get(thisCopy); + if(result == null) { + nodeTbl[thisCopy.level].put(thisCopy, thisCopy); + return thisCopy; + } + thisCopy.remove(nodeTbl); + return result; + } + + + public mddNode compress(HashMap[] nodeTbl) { + int mddHeight = nodeTbl.length; + + if(this.level < mddHeight-1) { + for(int blkIter = 0; blkIter < mddNode.numBlocks; blkIter++) { + if(this.nodeMap[blkIter] == null) + continue; + for(int arrayIter = 0; arrayIter < this.nodeMap[blkIter].length; arrayIter++) { + mddNode nextNode = this.nodeMap[blkIter][arrayIter]; + if(nextNode == null) + continue; + + mddNode newNextNode = nextNode.compress(nodeTbl); + if(newNextNode != nextNode) { + this.addSucc(blkIter, arrayIter, newNextNode); + } + } + } + } + mddNode newThis = nodeTbl[this.level].get(this); + if(newThis == null) { + nodeTbl[this.level].put(this, this); + return this; + } + else if(newThis != this) + return newThis; + + return this; + } + + /* + * Recursively remove this nodes and its successor nodes from nodeTbl if their reference + * count is 0. + */ + public void remove(HashMap[] nodeTbl) { + int mddHeight = nodeTbl.length; + + this.refCount--; + + if(this.refCount > 0) + return; + + if(this.level < mddHeight) { + if(this.level < mddHeight - 1) { + for(int blkIter = 0; blkIter < mddNode.numBlocks; blkIter++) { + if(this.nodeMap[blkIter] == null) + continue; + for(int arrayIter = 0; arrayIter < this.nodeMap[blkIter].length; arrayIter++) { + mddNode thisSucc = this.getSucc(blkIter, arrayIter); + if(thisSucc == null) + continue; + thisSucc.remove(nodeTbl); + } + } + } + nodeTbl[this.level].remove(this); + } + } + + + + /** + * Check if stateArray already exists in MDD. + * @param stateArray + * @param index + * @param terminal + * @return true if stateArray exists in MDD, false otherwise. + */ + public mddNode contains(int[] idxArray) { + if(this.level == -1) { + System.out.println("level is not right 2"); + System.exit(0); + } + + int curIdx = idxArray[this.level]; + int blockIdx = curIdx & mddNode.blockIdxMask; + int arrayIdx = curIdx >> mddNode.arrayIdxoffset; + + mddNode nextNode = this.getSucc(blockIdx, arrayIdx); + + if (nextNode == null) + return null; + + if (nextNode == Mdd.terminal) + return Mdd.terminal; + + return nextNode.contains(idxArray); + } + + /* + * Exhaustively fire all local LPN transitions from each local state in curStateArray + */ + public mddNode doLocalFirings(StateGraph[] curLpnArray, State[] curStateArray, + LinkedList[] nextSetArray, + mddNode reachSet, + HashMap[] nodeTbl) { + int curBlkIdx = curStateArray[this.level].getIndex() & mddNode.blockIdxMask; + int curArrayIdx = curStateArray[this.level].getIndex() >> mddNode.arrayIdxoffset; + + mddNode succ = Mdd.terminal; + if(this.level == curLpnArray.length - 1) { + this.addSucc(curBlkIdx, curArrayIdx, succ); + } + else if(this.level < curLpnArray.length) { + succ = new mddNode(); + succ.level = this.level + 1; + mddNode newSucc = succ.doLocalFirings(curLpnArray, curStateArray, nextSetArray, reachSet, nodeTbl); + this.addSucc(curBlkIdx, curArrayIdx, newSucc); + succ = newSucc; + } + + /* + * Do exhaustive local firings at this level. + */ + StateGraph curLpn = curLpnArray[this.level]; + State curState = curStateArray[this.level]; +// HashMap curLocalStateSet = localStateSets[this.level]; + nextSetArray[this.level].addLast(curState); + + LinkedList curEnabled = curLpn.getEnabled(curState); + LinkedList localTranSet = new LinkedList(); + if(curEnabled != null) { + for(Transition firedTran : curEnabled) + if(firedTran.isLocal()==true) + localTranSet.addLast(firedTran); + } + + if(localTranSet.size() == 0) { + mddNode newThis = nodeTbl[this.level].get(this); + if(newThis == null) { + nodeTbl[this.level].put(this, this); + return this; + } + this.remove(nodeTbl); + return newThis; + } + + HashSet curLocalNewStates = new HashSet(); + Stack stateStack = new Stack(); + Stack> enabledStack = new Stack>(); + + stateStack.push(curState); + enabledStack.push(localTranSet); + //LinkedList nextSet_tmp = new LinkedList(); + + while(stateStack.size() != 0) { + curState = stateStack.pop(); + LinkedList curLocalEnabled = enabledStack.pop(); + for(Transition tran2fire : curLocalEnabled) { + System.out.println("tran2fire = " + tran2fire.getLabel() + " in curlocalState = " + curState.getLabel()); + // TODO: Need to fix this. + State nextState = null; //tran2fire.fire(curLpnArray[tran2fire.getLpn().getIndex()], curState); + +// System.out.println("1 nextLocalState = " + nextState.getLabel()); + if(curLocalNewStates.contains(nextState) == true) + continue; + +// System.out.println("2 nextLocalState = " + nextState.getLabel()); + + curEnabled = curLpn.getEnabled(curState); + LinkedList nextEnabled = curLpn.getEnabled(nextState); + + // TODO: Need to fix this. + //Transition disabledTran = null; //tran2fire.disablingError(curEnabled, nextEnabled); + /* + if(disabledTran != null) { + System.err.println("Verification failed: disabling error: " + + disabledTran.getFullLabel() + " is disabled by " + + tran2fire.getFullLabel() + "!"); + System.exit(0); + } + */ + + //System.out.println("addlocal nextLocalState = " + nextState.getLabel()); + curLocalNewStates.add(nextState); + + // TODO: had to remove because nextState is null + //int nextBlkIdx = nextState.getIndex() & mddNode.blockIdxMask; + //int nextArrayIdx = nextState.getIndex() >> mddNode.arrayIdxoffset; + //this.addSucc(nextBlkIdx, nextArrayIdx, succ); + + LinkedList nextLocalEnabled = new LinkedList(); + //boolean nonLocalNext = false; + for(Transition tran : nextEnabled) { + if(tran.isLocal()==true) + nextLocalEnabled.addLast(tran); + //else + //nonLocalNext = true; + } + + // TODO: had to remove because nextState is null + //nextState.hasNonLocalEnabled(nonLocalNext); + //nextSetArray[this.level].addLast(nextState); + + if(nextLocalEnabled.size() == 0) + continue; + + stateStack.push(nextState); + enabledStack.push(nextLocalEnabled); + //System.out.println("added state " + nextState.getLabel() + " into localNewStateSet"); + +// for(int i = 0; i < curStateArray.length; i++) +// System.out.print(newNextStateArray[i].getLabel()+", "); +// System.out.println("\n#####################"); + } + } + + mddNode newThis = nodeTbl[this.level].get(this); + if(newThis == null) { + nodeTbl[this.level].put(this, this); + return this; + } + this.remove(nodeTbl); + return newThis; + } + + /* + * Return the successor node with index exists in nodeMap. + */ + private mddNode getSucc(int blockIdx, int arrayIdx) { + if(this.nodeMap[blockIdx]==null || arrayIdx >= this.nodeMap[blockIdx].length) + return null; + + return this.nodeMap[blockIdx][arrayIdx]; + } + + /* + * Insert a succNode with index into the nodeMap, whose size is automatically adjusted. + */ + private boolean addSucc(int blockIdx, int arrayIdx, mddNode succNode) { + //int oldsize = nodeMap.length; + + //boolean newState = false; + if(this.nodeMap[blockIdx]==null || arrayIdx >= this.nodeMap[blockIdx].length) { + this.resizeNodeMap(blockIdx, arrayIdx); + //newState = true; + //System.out.println(this + " >>> node level = " + level + " state label = " + index + " " + oldsize + " " + this.nodeMap.length); + } + + this.nodeMap[blockIdx][arrayIdx] = succNode; + succNode.refCount++; + this.blkHashVal[blockIdx] = Integer.rotateLeft(Arrays.hashCode(this.nodeMap[blockIdx]), this.level); + this.hashVal = 0; + nodeMapSize++; + return true; + } + + /* + * Resize the nodeMap so that an element with 'index' can be inserted into the nodeMap. + */ + private void resizeNodeMap(int blockIdx, int arrayIdx) { + if(this.nodeMap[blockIdx] == null) { + int newBlockSize = (arrayIdx / mddNode.blockSize + 1) * mddNode.blockSize; + try { + this.nodeMap[blockIdx] = new mddNode[newBlockSize]; + for (int i = 0; i < newBlockSize; i++) { + this.nodeMap[blockIdx][i] = null; + } + } catch (Exception e) { + String errorMessage = String.format( + "blockIdx=%s, arrayIdx=%s, newBlockSize=%s\n", + blockIdx, arrayIdx,newBlockSize); + throw new RuntimeException(errorMessage, e); + } + } + else if(arrayIdx >= this.nodeMap[blockIdx].length) { + int newBlockSize = (arrayIdx / mddNode.blockSize + 1) * mddNode.blockSize; + mddNode[] newBlock = new mddNode[newBlockSize]; + for(int i = 0; i < newBlock.length; i++) { + if(i < this.nodeMap[blockIdx].length) + newBlock[i] = this.nodeMap[blockIdx][i]; + else + newBlock[i] = null; + } + + this.nodeMap[blockIdx] = newBlock; + } + } + + @Override + public boolean equals(Object other) { + mddNode otherNode = (mddNode)other; + if(level != otherNode.level) + return false; + + for(int blkIter = 0; blkIter < mddNode.numBlocks; blkIter++) { + if(this.nodeMap[blkIter] == null && otherNode.nodeMap[blkIter] == null) + continue; + + if(this.nodeMap[blkIter] == null && otherNode.nodeMap[blkIter] != null) + return false; + + if(this.nodeMap[blkIter] != null && otherNode.nodeMap[blkIter] == null) + return false; + + if(this.nodeMap[blkIter].length != otherNode.nodeMap[blkIter].length) + return false; + + for(int arrayIter = 0; arrayIter < this.nodeMap[blkIter].length; arrayIter++) + if(this.nodeMap[blkIter][arrayIter] != otherNode.nodeMap[blkIter][arrayIter]) + return false; + } + return true; + } + + @Override + public int hashCode() { + if(hashVal == 0) + hashVal = Arrays.hashCode(this.blkHashVal); + + + return hashVal; + } + + public boolean subSet(mddNode other) { + for(int blkIter = 0; blkIter < mddNode.numBlocks; blkIter++) { + if(other.nodeMap[blkIter] == null && this.nodeMap[blkIter] != null) + return false; + if(this.nodeMap[blkIter] == null) + continue; + if(this.nodeMap[blkIter].length > other.nodeMap[blkIter].length) + return false; + for(int arrayIter = 0; arrayIter < this.nodeMap[blkIter].length; arrayIter++) { + mddNode thisSucc = this.getSucc(blkIter, arrayIter); + mddNode otherSucc = other.getSucc(blkIter, arrayIter); + if(thisSucc != null && otherSucc == null) + return false; + if(thisSucc != otherSucc) + return false; + } + } + return true; + } + + public int[] next(int mddHeight) { + if(maxArrayBound == -1) { + for(int blkIter = 0; blkIter < mddNode.numBlocks; blkIter++) + if(this.nodeMap[blkIter] != null && this.nodeMap[blkIter].length > maxArrayBound) + maxArrayBound = this.nodeMap[blkIter].length; + } + + for(int arrayIter = 0; arrayIter < maxArrayBound; arrayIter++) { + for(int blkIter = 0; blkIter < mddNode.numBlocks; blkIter++) { + mddNode thisSucc = this.getSucc(blkIter, arrayIter); + if(thisSucc == null) + continue; + + if(this.level == mddHeight-1) { + int stateIdx = (arrayIter << mddNode.arrayIdxoffset) | blkIter; + int[] result = new int[mddHeight]; + result[this.level] = stateIdx; + return result; + } + + int[] tmp = thisSucc.next(mddHeight); + if(tmp == null) + continue; + + int stateIdx = (arrayIter << mddNode.arrayIdxoffset) | blkIter; + tmp[this.level] = stateIdx; + return tmp; + } + } + return null; + } + + public int[] next(int mddHeight, int[] curIdxArray) { + int curIdx = curIdxArray[this.level]; + + // Find the largest array bound. + if(maxArrayBound == -1) { + for(int blkIter = 0; blkIter < mddNode.numBlocks; blkIter++) + if(this.nodeMap[blkIter] != null && this.nodeMap[blkIter].length > maxArrayBound) + maxArrayBound = this.nodeMap[blkIter].length; + } + + if(this.level == mddHeight-1) { + int newIdx = curIdx + 1; + int newBlkIdx = newIdx & mddNode.blockIdxMask; + int newArrayIdx = newIdx >> mddNode.arrayIdxoffset; + + for(int arrayIter = newArrayIdx; arrayIter < maxArrayBound; arrayIter++) { + int startingBlkIdx = (arrayIter > newArrayIdx) ? 0 : newBlkIdx; + for(int blkIter = startingBlkIdx; blkIter < mddNode.numBlocks; blkIter++) { +// if(this.nodeMap[blkIter] == null) +// continue; + mddNode thisSucc = this.getSucc(blkIter, arrayIter); + if(thisSucc == null) + continue; + + int stateIdx = (arrayIter << mddNode.arrayIdxoffset) | blkIter; + int[] result = new int[mddHeight]; + result[this.level] = stateIdx; + return result; + } + } + return null; + } + int curBlkIdx = curIdx & mddNode.blockIdxMask; + int curArrayIdx = curIdx >> mddNode.arrayIdxoffset; + mddNode thisSucc = this.getSucc(curBlkIdx, curArrayIdx); + int[] tmp = thisSucc.next(mddHeight, curIdxArray); + if(tmp != null) { + tmp[this.level] = curIdx; + return tmp; + } + + int newIdx = curIdx + 1; + int newBlkIdx = newIdx & mddNode.blockIdxMask; + int newArrayIdx = newIdx >> mddNode.arrayIdxoffset; + + for(int arrayIter = newArrayIdx; arrayIter < maxArrayBound; arrayIter++) { + int startingBlkIdx = (arrayIter > newArrayIdx) ? 0 : newBlkIdx; + for(int blkIter = startingBlkIdx; blkIter < mddNode.numBlocks; blkIter++) { +// if(this.nodeMap[blkIter] == null) +// continue; + thisSucc = this.getSucc(blkIter, arrayIter); + if(thisSucc == null) + continue; + + int stateIdx = (arrayIter << mddNode.arrayIdxoffset) | blkIter; + int[] result = thisSucc.next(mddHeight); + result[this.level] = stateIdx; + return result; + } + } + return null; + } + + + public void increaseRefCnt() { + refCount++; + } + + public void decreaseRefCnt() { + if(refCount == 1) { + System.out.println("Cannot decrease the ref count of 1"); + System.exit(0); + } + refCount--; + } + + public int getRefCount() { + return refCount; + } + + public int getSuccSize() { + return nodeMap.length; + } + + public double pathCount(HashSet uniqueNodes) { + uniqueNodes.add(this); + double paths = 0.0; + + if(this == Mdd.terminal) + return paths; + + for(int blkIter = 0; blkIter != mddNode.numBlocks; blkIter++) { + if(this.nodeMap[blkIter] == null) + continue; + + for(int arrayIter = 0; arrayIter < this.nodeMap[blkIter].length; arrayIter++) { + if(this.nodeMap[blkIter][arrayIter] == null) + continue; + + if(this.nodeMap[blkIter][arrayIter] == Mdd.terminal) + paths += 1; + else + paths += nodeMap[blkIter][arrayIter].pathCount(uniqueNodes); + } + } + return paths; + } + + public void print() { + if(nodeMap.length == 0) + return; + + for(int blkIter = 0; blkIter < mddNode.numBlocks; blkIter++) { + if(this.nodeMap[blkIter] == null) + continue; + + for(int arrayIter = 0; arrayIter < nodeMap[blkIter].length; arrayIter++) { + if(this.nodeMap[blkIter][arrayIter] == null) + continue; + System.out.println(this + " level = " + level + ", " + (blkIter + (arrayIter << mddNode.arrayIdxoffset)) + " -> " + nodeMap[blkIter][arrayIter] + " refCount = " + nodeMap[blkIter][arrayIter].refCount); + nodeMap[blkIter][arrayIter].print(); + } + } + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/mdtNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/mdtNode.java new file mode 100644 index 000000000..3d5f25634 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/MDD/mdtNode.java @@ -0,0 +1,174 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.MDD; + +import java.util.*; + +import edu.utah.ece.async.lema.verification.platu.stategraph.*; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class mdtNode { + //private Stack localStateSet; + int level; + private HashMap nodeMap; + + mdtNode() { + //localStateSet = new Stack(); + this.level = 0; + this.nodeMap = new HashMap(); + } + + public boolean push(State[] curIdxArray, int level) { + State curIdx = curIdxArray[this.level]; + mdtNode nextNode = this.nodeMap.get(curIdx); + if(nextNode != null) { + if(this.level == curIdxArray.length-1) { + return false; + } + nextNode.push(curIdxArray, level+1); + return true; + } + if(this.level == curIdxArray.length-1) + this.nodeMap.put(curIdx, MDT.terminal); + else { + nextNode = new mdtNode(); + nextNode.level = this.level + 1; + nextNode.push(curIdxArray, level+1); + this.nodeMap.put(curIdx, nextNode); + } + //this.localStateSet.push(curIdx); + return true; + } + + public State[] pop(State[] prjState) { + //State[] prjState = null; + //State curLocalState = localStateSet.peek(); + State curLocalState = null; + Set keySet = this.nodeMap.keySet(); + + for(State st : keySet) { + curLocalState = st; + break; + } + prjState[this.level] = curLocalState; + mdtNode nextNode = this.nodeMap.get(curLocalState); + if(nextNode == MDT.terminal) { + prjState[level] = curLocalState; + this.nodeMap.remove(curLocalState); + } + else { + prjState = nextNode.pop(prjState); + if(nextNode.empty()==true) { + this.nodeMap.remove(curLocalState); + } + } + + return prjState; + } + + public Stack popList(State[] prjState) { + //State[] prjState = null; + //State curLocalState = localStateSet.peek(); + State curLocalState = null; + Set keySet = this.nodeMap.keySet(); + Stack stateArrayList = null; + + if(this.level == prjState.length-1) { + Stack prjStateList = new Stack(); + for(State st : keySet) { + State[] stateArray = prjState.clone(); + stateArray[this.level] = st; + prjStateList.push(stateArray); + } + this.nodeMap = null; + return prjStateList; + } + + for(State st : keySet) { + curLocalState = st; + break; + } + prjState[this.level] = curLocalState; + mdtNode nextNode = this.nodeMap.get(curLocalState); + if(nextNode == MDT.terminal) { + //Stack results = new Stack(); + //prjState = new State[level+1]; + //prjState[level] = curLocalState; + //this.localStateSet.pop(); + this.nodeMap.remove(curLocalState); + } + else { + stateArrayList = nextNode.popList(prjState); + //prjState[level] = curLocalState; + if(nextNode.empty()==true) { + //this.localStateSet.pop(); + this.nodeMap.remove(curLocalState); + } + } + + return stateArrayList; + } + +// public State[] peek(int level) { +// State[] prjState = null; +// State curLocalState = this.localStateSet.peek(); +// mdtNode nextNode = this.nodeMap.get(curLocalState); +// if(nextNode == MDT.terminal) { +// prjState = new State[level+1]; +// } +// else { +// prjState = nextNode.peek(level+1); +// } +// +// prjState[level] = curLocalState; +// return prjState; +// } + + public boolean contains(State[] curIdxArray, int level) { +// if(this.localStateSet.search(curIdxArray[level])==-1) +// return false; + + if(this.nodeMap.get(curIdxArray[level]) == null) + return false; + + if(level == curIdxArray.length-1) + return true; + mdtNode nextNode = this.nodeMap.get(curIdxArray[level]); + return nextNode.contains(curIdxArray, level+1); + } + + public boolean empty() { + return (this.nodeMap==null || this.nodeMap.size() == 0); + } + + public int nodeCnt() { + if(this.nodeMap == null) + return 1; + + int totalChildren = 0; + Set keySet = this.nodeMap.keySet(); + for(State st : keySet) + totalChildren += this.nodeMap.get(st).nodeCnt(); + + return totalChildren + 1; + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/DBM.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/DBM.java new file mode 100644 index 000000000..c98ce6100 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/DBM.java @@ -0,0 +1,223 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.TimingAnalysis; + +import java.util.*; + +import edu.utah.ece.async.lema.verification.platu.common.Pair; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class DBM { + + private int[][] matrix; + private int hashVal; + private int refCount; + + DBM(int dim) { + matrix = new int[dim][dim]; + for(int x = 0; x < dim; x++) + for(int y = 0; y < dim; y++) + matrix[x][y] = 0; + this.hashVal = 0; + this.refCount = 0; + } + + public DBM(DBM other) { + this.hashVal = other.hashVal; + int dim = other.dimension(); + this.matrix = new int[dim][dim]; + for(int x = 0; x < dim; x++) + for(int y = 0; y < dim; y++) + this.matrix[x][y] = other.matrix[x][y]; + this.refCount = 0; + } + + /** + * + * @return + */ + final public int dimension() { + return this.matrix.length; + } + + @Override + public Object clone() { + return new DBM(this); + } + + public void assign(int x, int y, int val) { + matrix[x][y] = val; + this.hashVal = 0; + } + + public int value(int x, int y) { + return matrix[x][y]; + } + + public void canonicalize() { + int dim = matrix.length; + for(int x = 0; x < dim; x++) + for(int y = 0; y < dim; y++) { + if(x==y) continue; + for(int i = 0; i < dim; i++) { + if(i==x || i==y) continue; + if(matrix[x][i]==edu.utah.ece.async.lema.verification.platu.common.Common.INFINITY || matrix[i][y]==edu.utah.ece.async.lema.verification.platu.common.Common.INFINITY) + continue; + if(matrix[x][y] > matrix[x][i] + matrix[i][y]) + matrix[x][y] = matrix[x][i] + matrix[i][y]; + } + } + + hashVal = 0; + } + + public void restrict(int x, int value) { + this.matrix[x][0] = -value; + this.hashVal = 0; + } + + public DBM merge(DBM other) { + int dim = this.dimension(); + + DBM newDbm = new DBM(dim); + + for(int i = 0; i < dim; i++) + for(int j = 0; j < dim; j++) { + int maxVal_ij = this.value(i, j) > other.value(i, j) ? this.value(i, j) : other.value(i, j); + int maxVal_ji = this.value(j, i) > other.value(j, i) ? this.value(j, i) : other.value(j, i); + newDbm.assign(i, j, maxVal_ij); + newDbm.assign(j, i, maxVal_ji); + } + + return newDbm; + } + + /* + * Check if this DBM is a subset of the other DBM. + */ + public boolean subset(DBM other) { + int dim = this.dimension(); + for(int x = 0; x < dim; x++) + for(int y = 0; y < dim; y++) { + if(this.matrix[x][y] > other.matrix[x][y]) + return false; + } + return true; + } + + /* + * Return a DBM with all redundant edges removed. + * @see 'Timed Automata: Semantics, Algorithms and Tools + */ + public HashMap, Integer> getMinConstr() { + int dim = matrix.length; + + HashMap, Integer> constrSet = new HashMap, Integer>(); + for(int x = 0; x < dim; x++) + for(int y = 0; y < dim; y++) { + if(x==y) continue; + for(int i = 0; i < dim; i++) { + if(i==x || i==y) continue; + if(matrix[x][i]==edu.utah.ece.async.lema.verification.platu.common.Common.INFINITY || matrix[i][y]==edu.utah.ece.async.lema.verification.platu.common.Common.INFINITY) + continue; + if(matrix[x][i] + matrix[i][y] > matrix[x][y]) + constrSet.put(new Pair(x,y), this.matrix[x][y]); + } + } + return constrSet; + } + + + @Override + final public int hashCode() { + if(this.hashVal != 0) + return hashVal; + + int dim = matrix.length; + int[] tmp_hash = new int[dim]; + for(int i = 0; i < dim; i++) + tmp_hash[i] = Integer.rotateLeft(Arrays.hashCode(this.matrix[i]), i); + + return Arrays.hashCode(tmp_hash); + } + + /** + * + * @param o + * @return + */ + @Override + final public boolean equals(Object other) { + DBM otherDbm = (DBM)other; + if (this.matrix == otherDbm.matrix) + return true; + + int dim = this.dimension(); + if(this.dimension() != otherDbm.dimension()) + return false; + + for(int x = 0; x < dim; x++) + for(int y = 0; y < dim; y++) + if(this.matrix[x][y] != otherDbm.matrix[x][y]) + return false; + + return true; + } + + @Override + public String toString() { + int dim = this.dimension(); + String strOut = new String(); + for(int x = 0; x < dim; x++) { + for(int y = 0; y < dim; y++) { + if(this.matrix[x][y] == edu.utah.ece.async.lema.verification.platu.common.Common.INFINITY) + strOut += "\tINF"; + else + strOut += "\t" + this.matrix[x][y]; + } + strOut += "\n"; + } + + return strOut + "\n"; + } + + public int[] signature() { + int dim = this.dimension(); + int[] result = new int[this.dimension() * this.dimension()]; + + for(int i = 0; i < this.dimension(); i++) + for(int j = 0; j < this.dimension(); j++) { + int pos = i * dim + j; + result[pos] = this.matrix[i][j]; + } + + return result; + } + + public void incRefCnt() { + this.refCount++; + } + + public int decrRefCnt() { + this.refCount--; + return this.refCount; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/Poset.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/Poset.java new file mode 100644 index 000000000..13b8b0b83 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/Poset.java @@ -0,0 +1,257 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.TimingAnalysis; + +import java.util.*; + +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.platuLpn.*; + +/** + * This class implements the POSET algorithm in C Myers's book, section 7.5. + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Poset { + public static final int INFINITY = edu.utah.ece.async.lema.verification.platu.common.Common.INFINITY; + + protected HashMap> causalityFwd; + protected HashMap causalityBwd; + protected DualHashMap tranIdxMap; + protected DBM dbm; + + public Poset() { + causalityFwd = null; + causalityBwd = null; + tranIdxMap = null; + dbm = null; + } + + public void initialize(Transition firedTran, LpnTranList[] nextEnabledArray) { + causalityFwd = new HashMap>(); + causalityBwd = new HashMap(); + HashSet enabledSet = new HashSet(); + for(int i = 0; i < nextEnabledArray.length; i++) + if(nextEnabledArray[i] != null) + for(Transition tran : nextEnabledArray[i]) { + enabledSet.add(tran); + this.causalityBwd.put(tran, firedTran); + } + this.causalityFwd.put(firedTran, enabledSet); + + this.tranIdxMap = new DualHashMap(); + this.tranIdxMap.insert(firedTran, this.tranIdxMap.size()); + + this.dbm = new DBM(1); + } + + public Poset update(Transition firedTran, LpnTranList[] curEnabledArray, LpnTranList[] nextEnabledArray) { + Poset newPoset = new Poset(); + + newPoset.tranIdxMap = new DualHashMap(); + for(int i = 0; i < this.tranIdxMap.size(); i++) { + Transition tran = this.tranIdxMap.getKey(i); + newPoset.tranIdxMap.insert(tran, i); + } + + newPoset.causalityBwd = (HashMap) this.causalityBwd.clone(); + newPoset.causalityFwd = new HashMap>(); + DBM dbmCopy = new DBM(this.dbm.dimension() + 1); + + for(int i = 0; i < this.tranIdxMap.size(); i++) { + Transition curTran = newPoset.tranIdxMap.getKey(i); + HashSet curEnabledSet = this.causalityFwd.get(curTran); + if(curEnabledSet==null) { + System.out.println("*** Transition does not exist in causalityFwd"); + return null; + } + newPoset.causalityFwd.put(curTran, (HashSet)curEnabledSet.clone()); + + for(int j = 0; j < this.tranIdxMap.size(); j++) { + dbmCopy.assign(i, j, this.dbm.value(i, j)); + } + } + + /* + * Adjust newPoset with firedTran + */ + + // Find the new enabled transition due to firedTran. + HashSet curEnabledSet = new HashSet(); + HashSet newEnabledSet = new HashSet(); + + for(int i = 0; i < curEnabledArray.length; i++) { + if(curEnabledArray[i] != null) + for(Transition tran : curEnabledArray[i]) + curEnabledSet.add(tran); + } + + for(int i = 0; i < nextEnabledArray.length; i++) { + if(nextEnabledArray[i] != null) + for(Transition tran : nextEnabledArray[i]) + if(curEnabledSet.contains(tran) == false) { + newEnabledSet.add(tran); + newPoset.causalityBwd.put(tran, firedTran); + } + } + + newPoset.causalityFwd.put(firedTran, newEnabledSet); + newPoset.tranIdxMap.insert(firedTran, newPoset.tranIdxMap.size()); + + // Add the firedTran into newPoset, and set its time separations with other transitions in newPoset. + int firedTranIdx = newPoset.tranIdxMap.getValue(firedTran); + for(int i = 0; i < newPoset.tranIdxMap.size(); i++) { + Transition prevTran = newPoset.tranIdxMap.getKey(i); + if(prevTran == firedTran) continue; + + HashSet prevEnabledSet = newPoset.causalityFwd.get(prevTran); + if(prevEnabledSet.contains(firedTran) == true) { + // TODO: Get upper and lower bounds for our LPN? + //dbmCopy.assign(firedTranIdx, i, firedTran.getDelayUB()); + //dbmCopy.assign(i, firedTranIdx, -firedTran.getDelayLB()); + } + else { + dbmCopy.assign(i, firedTranIdx, INFINITY); + dbmCopy.assign(firedTranIdx, i, INFINITY); + } + } + + dbmCopy.canonicalize(); + + /* + * Projecting the useless transitions from newPoset. + */ + Transition firedEnabling = newPoset.causalityBwd.get(firedTran); + HashSet firedSiblings = newPoset.causalityFwd.get(firedEnabling); + firedSiblings.remove(firedTran); + +// System.out.println("tranIdxMap"); +// for(int i = 0; i < newPoset.tranIdxMap.size(); i++) { +// LPNTran thisTran = newPoset.tranIdxMap.getKey(i); +// System.out.print(thisTran.getFullLabel()+", "); +// } +// System.out.println(""); + HashSet uselessTranSet = new HashSet(); + for(int i = 0; i < newPoset.tranIdxMap.size(); i++) { + Transition thisTran = newPoset.tranIdxMap.getKey(i); +// HashSet thisEnabledSet = newPoset.causalityFwd.get(thisTran); +// boolean useless = true; +// System.out.print(thisTran.getFullLabel() + " : "); +// for(LPNTran enabled : thisEnabledSet) { + //System.out.print(thisTran.getFullLabel() + ", "); + //if(newPoset.tranIdxMap.getValue(enabled) == null) { + if(newPoset.causalityFwd.get(thisTran).size() == 0) { +// useless = false; +// break; +// } + //} + //System.out.println("\n"); + //if(useless==true) + uselessTranSet.add(thisTran); + } + } + + for(Transition uselessTran : uselessTranSet) { + HashSet uselessTranEnabled = newPoset.causalityFwd.get(uselessTran); + for(Transition tran : uselessTranEnabled) { + newPoset.causalityBwd.remove(tran); + } + newPoset.causalityFwd.remove(uselessTran); + } + + DualHashMap newTranIdxMap = new DualHashMap(); + for(int i = 0; i < newPoset.tranIdxMap.size(); i++) { + Transition tran_i = newPoset.tranIdxMap.getKey(i); + if(uselessTranSet.contains(tran_i) == false) { + newTranIdxMap.insert(tran_i, newTranIdxMap.size()); + } + } + + DualHashMap oldTranIdxMap = newPoset.tranIdxMap; + newPoset.tranIdxMap = newTranIdxMap; + + /* + * Adjust dbmCopy by removing the entries w.r.t newTranIdxMap + */ + newPoset.dbm = new DBM(newPoset.tranIdxMap.size()); + for(int new_i = 0; new_i < newPoset.tranIdxMap.size(); new_i++) { + Transition new_tran_i = newPoset.tranIdxMap.getKey(new_i); + int old_i = oldTranIdxMap.getValue(new_tran_i); + for(int new_j = 0; new_j < newPoset.tranIdxMap.size(); new_j++) { + Transition new_tran_j = newPoset.tranIdxMap.getKey(new_j); + int old_j = oldTranIdxMap.getValue(new_tran_j); + newPoset.dbm.assign(new_i, new_j, dbmCopy.value(old_i, old_j)); + newPoset.dbm.assign(new_j, new_i, dbmCopy.value(old_j, old_i)); + } + } + + return newPoset; + } + + /* + * Return the time separation between two transitions as defined in this Poset. + */ + public int getTimeSep(Transition tran_i, Transition tran_j) { + Transition enablingTran_i = this.causalityBwd.get(tran_i); + Transition enablingTran_j = this.causalityBwd.get(tran_j); + int i = this.tranIdxMap.getValue(enablingTran_i); + int j = this.tranIdxMap.getValue(enablingTran_j); + return this.dbm.value(i, j); + } + + @Override + public int hashCode() { + return Integer.rotateLeft(this.tranIdxMap.hashCode(), 11) ^ Integer.rotateLeft(this.dbm.hashCode(), 7); + } + + @Override + public boolean equals(Object other) { + Poset otherPoset = (Poset)other; + if(this.tranIdxMap.equals(otherPoset.tranIdxMap)==false) + //if(this.enabledSet != otherZone.enabledSet) + return false; + +// System.out.println("this zone : " + this.dbm); +// System.out.println("\nother zone : " + otherZone.dbm + "\n ================================="); + + if(this.dbm.equals(otherPoset.dbm)==false) + //if(this.dbm != otherZone.dbm) + return false; + +// if(this.timeSep == null && otherZone.timeSep == null) +// return true; +// +// if((this.timeSep == null && otherZone.timeSep != null) || (this.timeSep != null && otherZone.timeSep == null)) +// return false; +// +// if(this.timeSep.equals(otherZone.timeSep) == false) +// return false; + + return true; + } + + @Override + public String toString() { + String ret = new String(); + for(int i = 0; i < this.tranIdxMap.size(); i++) { + ret += "\t" + this.tranIdxMap.getKey(i).getFullLabel(); + } + String timeSepConstraints = new String(); + + return ret + "\n\n" + this.dbm.toString() + timeSepConstraints +"\n"; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/PrjStateZone.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/PrjStateZone.java new file mode 100644 index 000000000..76d2f4822 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/PrjStateZone.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.TimingAnalysis; + +import java.util.Arrays; + +import edu.utah.ece.async.lema.verification.platu.TimingAnalysis.Zone1; +import edu.utah.ece.async.lema.verification.platu.stategraph.*; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class PrjStateZone { + State[] stateArray; + Zone1 zone; + + public PrjStateZone(final State[] other, Zone1 zone) { + this.stateArray = other; + this.zone = zone; + } + + + @Override + public boolean equals(final Object other) { + PrjStateZone otherSt = (PrjStateZone)other; + for(int i = 0; i < this.stateArray.length; i++) + if(this.stateArray[i] != otherSt.stateArray[i]) + return false; + return this.zone==otherSt.zone; + } + + @Override + public int hashCode() { + return Arrays.hashCode(this.stateArray) ^ zone.hashCode(); + } + + /** + * @return the zone + */ + public Zone1 getZone() { + return zone; + } + + public State[] getStateArray() { + return stateArray; + } + + @Override + public String toString() { + return Arrays.toString(stateArray)+zone.hashCode(); + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/TimingAnalysis.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/TimingAnalysis.java new file mode 100644 index 000000000..0f43fd9b4 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/TimingAnalysis.java @@ -0,0 +1,791 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.TimingAnalysis; + +import java.util.*; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.TimingAnalysis.DBM; +import edu.utah.ece.async.lema.verification.platu.TimingAnalysis.Poset; +import edu.utah.ece.async.lema.verification.platu.TimingAnalysis.Zone1; +import edu.utah.ece.async.lema.verification.platu.logicAnalysis.Analysis; +import edu.utah.ece.async.lema.verification.platu.platuLpn.DualHashMap; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LpnTranList; +import edu.utah.ece.async.lema.verification.platu.project.PrjState; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class TimingAnalysis { + + /* + * Data member section + */ + HashMap[] timingStateCache; + + /* + * Member function section + */ + public TimingAnalysis(final StateGraph[] SgArray) { + + int ArraySize = SgArray.length; + + timingStateCache = new HashMap[ArraySize]; + + long start = System.currentTimeMillis(); + + // Initialize the project state + HashMap varValMap = new HashMap(); + State[] initStateArray = new State[ArraySize]; + ArrayList> enabledList = new ArrayList>( + 1); + for (int index = 0; index < ArraySize; index++) { + LPN curLpn = SgArray[index].getLpn(); + StateGraph curSg = SgArray[index]; + // TODO: (Check) check if curSg is correct + initStateArray[index] = curSg.genInitialState(); + int[] curStateVector = initStateArray[index].getVariableVector(); + HashSet outVars = (HashSet) curLpn.getAllOutputs().keySet(); + DualHashMap VarIndexMap = curLpn.getVarIndexMap(); + for (String var : outVars) { + varValMap.put(var, curStateVector[VarIndexMap.getValue(var)]); + } + + } + // Adjust the value of the input variables in LPN in the initial state. + for (int index = 0; index < ArraySize; index++) { + StateGraph curLpn = SgArray[index]; + initStateArray[index].update(curLpn,varValMap, curLpn.getLpn().getVarIndexMap()); + initStateArray[index] = curLpn.addState(initStateArray[index]); + enabledList.add(index, curLpn.getEnabled(initStateArray[index])); + } + + if (Analysis.deadLock(SgArray, initStateArray) == true) { + System.err + .println("Verification failed: deadlock in the initial state."); + return; + } + + // Add the initial project state into the prjStateSet, and invoke + // findsg_recursive(). + HashSet stateTrace = new HashSet(1); + PrjState curPrjState = new PrjState(initStateArray); + stateTrace.add(curPrjState); + + LinkedList traceCex = new LinkedList(); + + /* + * Timing analysis by DFS + */ + //this.search_dfs(SgArray, initStateArray); + TimingAnalysis.search_dfs_abstraction(SgArray, initStateArray); + // this.search_dfs_split_zone(SgArray, initStateArray); + + while (traceCex.size() > 0) { + Transition lpnTran = traceCex.removeFirst(); + System.out.println(lpnTran.getLpn().getLabel() + " : " + + lpnTran.getLabel()); + } + + System.out.println("Modules' local states: "); + for (int i = 0; i < ArraySize; i++) { + System.out.println("module " + SgArray[i].getLpn().getLabel() + ": " + + SgArray[i].reachSize()); + } + + long elapsedTimeMillis = System.currentTimeMillis() - start; + float elapsedTimeSec = elapsedTimeMillis / 1000F; + + System.out.println("---> total runtime: " + elapsedTimeSec + " sec\n");// + } + + @SuppressWarnings("unused") + private static void search_dfs(StateGraph[] lpnList, State[] initStateArray) { + System.out.println("---> Calling TimingAnalysis.search_dfs"); + + //int zoneType = 0; + + int arraySize = lpnList.length; + int max_stack_depth = 0; + long peakTotalMem = 0; + long peakUsedMem = 0; + boolean failure = false; + + /* + * Create objects to hold state space information + */ + HashMap> prjStateZoneSet = new HashMap>(); + // /* + // * Compute the set of input transitions for each module + // */ + // HashSet[] inputTranSetArray = new HashSet[arraySize]; + // for(int i = 0; i curInputTranSet = new HashSet(); + // HashSet inputVarSet = curLpn.getInputs(); + // for(int other_i = 0; other_i assignedVarSet = other_tran.getAssignedVar(); + // for(String assignedVar : assignedVarSet) + // if(inputVarSet.contains(assignedVar)==true) { + // curInputTranSet.add(other_tran); + // break; + // } + // } + // } + // inputTranSetArray[i] = curInputTranSet; + // } + // + // for(int i = 0; i)inputTranSetArray[i]) { + // System.out.print(tran.getFullLabel() + " "); + // } + // System.out.println("---------------------"); + // } + + /* + * Compute the untimed enabled transition arrays in the initial state + */ + LpnTranList[] initEnabledArray = new LpnTranList[arraySize]; + ArrayList> enabledArrayList = new ArrayList>(); + for (int i = 0; i < arraySize; i++) { + LpnTranList tmp = lpnList[i].getEnabled(initStateArray[i]); + initEnabledArray[i] = tmp; + enabledArrayList.add(i, tmp); + } + + /* + * Compute the initial zone, project the zone to each module, and + * enlarge the zone corresponding to the zone projection. + */ + Zone1 initZone = new Zone1(); + initZone.initialize(initEnabledArray); + + /* + * Compute the timed enabled transitions in the initial state + */ + LpnTranList initTimedEnabled = new LpnTranList(); + for (int i = 0; i < arraySize; i++) { + for (Transition tran : initEnabledArray[i]) + if (initZone.checkTiming(tran) == true) + initTimedEnabled.addLast(tran); + } + + if (initTimedEnabled.size() == 0) { + System.err + .println("---> ERROR: Verification failed: deadlock in the initial state."); + failure = true; + return; + } + + /* + * Initializing the stacks needed for search. + */ + Stack stateStack = new Stack(); + Stack zone1Stack = new Stack(); + Stack posetStack = new Stack(); + Stack lpnTranStack = new Stack(); + + stateStack.push(initStateArray); + zone1Stack.push(initZone); + posetStack.push(null); + lpnTranStack.push(initTimedEnabled); + + PrjState initPrjState = new PrjState(initStateArray); + HashSet initStateZoneSet = prjStateZoneSet.get(initPrjState); + if (initStateZoneSet == null) { + initStateZoneSet = new HashSet(); + initStateZoneSet.add(initZone.getDbm()); + prjStateZoneSet.put(initPrjState, initStateZoneSet); + } else + initStateZoneSet.add(initZone.getDbm()); + + int tranFiringCnt = 0; + int iterations = 0; + + /* + * Main search loop. + */ + main_while_loop: while (failure == false && stateStack.empty() == false) { + iterations++; + + long curTotalMem = Runtime.getRuntime().totalMemory(); + long curUsedMem = Runtime.getRuntime().totalMemory() + - Runtime.getRuntime().freeMemory(); + + if (curTotalMem > peakTotalMem) + peakTotalMem = curTotalMem; + + if (curUsedMem > peakUsedMem) + peakUsedMem = curUsedMem; + + // if(iterations == 200) System.exit(0); + if (iterations % 2000 == 0) { + System.out.println("---> #iteration " + iterations + + "> # LPN transition firings: " + tranFiringCnt + + ", # of zones: " + Zone1.uniqueCache.size() + + ", max_stack_depth: " + max_stack_depth + + " used memory: " + (float) curUsedMem / 1000000 + + " free memory: " + + (float) Runtime.getRuntime().freeMemory() / 1000000); + } + + if (stateStack.size() > max_stack_depth) { + max_stack_depth = stateStack.size(); + } + + State[] curStateArray = stateStack.peek(); + Zone1 curZone = zone1Stack.peek(); + Poset curPoset = posetStack.peek(); + LpnTranList curTimedEnabled = lpnTranStack.peek(); + + if (curTimedEnabled.size() == 0) { + stateStack.pop(); + zone1Stack.pop(); + posetStack.pop(); + lpnTranStack.pop(); + continue main_while_loop; + } + + Transition firedTran = curTimedEnabled.removeLast(); + + // System.out.println("firedTran " + firedTran.getFullLabel()); + // TODO: fire has been moved to StateGraph. + State[] nextStateArray = null;//firedTran.fire(lpnList, curStateArray); + tranFiringCnt++; + + LpnTranList[] curEnabledArray = new LpnTranList[arraySize]; + LpnTranList[] nextEnabledArray = new LpnTranList[arraySize]; + for (int i = 0; i < arraySize; i++) { + StateGraph lpn_tmp = lpnList[i]; + LpnTranList enabledList = null; + enabledList = lpn_tmp.getEnabled(curStateArray[i]); + curEnabledArray[i] = enabledList; + // TODO: have to cut below because NULL + //enabledList = lpn_tmp.getEnabled(nextStateArray[i]); + //nextEnabledArray[i] = enabledList.clone(); + } + + // System.out.println(curZone); + // System.out.println("\nfiredTran = " + firedTran.getFullLabel() + + // "\n"); + Poset nextPoset = null; + if (curPoset == null) { + nextPoset = new Poset(); + nextPoset.initialize(firedTran, nextEnabledArray); + } else { + nextPoset = curPoset.update(firedTran, curEnabledArray, + nextEnabledArray); + } + + // System.out.println(nextPoset); + + Zone1 nextZone = curZone.update(firedTran, nextEnabledArray); + // nextZone.enlarge(nextEnabledArray, inputTranSetArray); + // Zone1 pZone = new Zone1(nextPoset, nextEnabledArray); + + // System.out.println(nextZone + + // "\n---------------------------------\n");// + pZone + + // "\n========================================\n"); + + // /* + // * Check if nextZone already exists in the cache. If so, get the + // existing copy. + // */ + // Zone1 newNextZone1 = Zone1.uniqueCache.get(nextZone); + // if(newNextZone1 == null) { + // Zone1.uniqueCache.put(nextZone, nextZone); + // System.out.println(nextZone + "\n " + Zone1.uniqueCache.size() + + // "\n---------------------------------\n"); + // } + // else { + // nextZone = newNextZone1; + // } + + /* + * Compute the timed enabled transitions w.r.t nextZone. + */ + LpnTranList nextTimedEnabled = new LpnTranList(); + for (int i = 0; i < arraySize; i++) { + LpnTranList tmp = nextEnabledArray[i]; + for (Transition tran : tmp) { + if (nextZone.checkTiming(tran) == true) + nextTimedEnabled.addLast(tran); + } + } + + /* + * Check disabling error + */ + // TODO: disablingError was moved to StateGraph. + Transition disabledTran = null;//firedTran.disablingError(curTimedEnabled, + // nextTimedEnabled); + // TODO: dead code + /* + if (disabledTran != null) { + System.out.println("---> Disabling Error: " + + disabledTran.getFullLabel() + " is disabled by " + + firedTran.getFullLabel()); + + System.out.println("Current state:"); + for (int ii = 0; ii < arraySize; ii++) { + System.out.println("module " + lpnList[ii].getLpn().getLabel()); + System.out.println(curStateArray[ii]); + System.out.println("Enabled set: " + curEnabledArray[ii]); + } + System.out.println("Timed enabled transitions: " + + curTimedEnabled); + + System.out.println("======================\nNext state:"); + for (int ii = 0; ii < arraySize; ii++) { + System.out.println("module " + lpnList[ii].getLpn().getLabel()); + System.out.println(nextStateArray[ii]); + System.out.println("Enabled set: " + nextEnabledArray[ii]); + } + System.out.println("Timed enabled transitions: " + + nextTimedEnabled); + + System.out.println(); + + failure = true; + break main_while_loop; + } + */ + + /* + * Check deadlock. + */ + if (nextTimedEnabled.size() == 0) { + System.out.println("---> ERROR: Verification failed: deadlock."); + for (int ii = 0; ii < arraySize; ii++) { + System.out.println("module " + lpnList[ii].getLpn().getLabel()); + //System.out.println(nextStateArray[ii]); + System.out.println("Enabled set: " + nextEnabledArray[ii]); + } + System.out.println("Zone: " + nextZone); + failure = true; + continue main_while_loop; + } + + /* + * Add the new timed state, and check if this is a new timed state. + * Zone subset relation is checked to reduce redundant zones. + */ + boolean isNew = false; + PrjState nxtPrjState = new PrjState(nextStateArray); + HashSet nxtStateZoneSet = prjStateZoneSet.get(nxtPrjState); + if (nxtStateZoneSet == null) { + nxtStateZoneSet = new HashSet(); + nxtStateZoneSet.add(nextZone.getDbm()); + prjStateZoneSet.put(nxtPrjState, nxtStateZoneSet); + isNew = true; + } + else { + LinkedList subsetDBMs = new LinkedList(); + boolean isSubset = false; + for (Object old : nxtStateZoneSet) { + DBM oldDbm = (DBM) old; + if (isSubset == false && nextZone.getDbm().subset(oldDbm) == true) + isSubset = true; + else if (oldDbm.subset(nextZone.getDbm()) == true) + subsetDBMs.addLast(oldDbm); + } + + if (isSubset == false) { + nxtStateZoneSet.add(nextZone.getDbm()); + isNew = true; + } + + for (DBM d : subsetDBMs) + nxtStateZoneSet.remove(d); + } + + if (isNew == true) { + stateStack.push(nextStateArray); + zone1Stack.push(nextZone); + posetStack.push(nextPoset); + lpnTranStack.push(nextTimedEnabled); + } + } + + int dbmCnt = 0; + Set stateSet = prjStateZoneSet.keySet(); + HashSet allDbmSet = new HashSet(); + for (PrjState curState : stateSet) { + HashSet curDbmSet = prjStateZoneSet.get(curState); + for (DBM dbm_i : curDbmSet) + allDbmSet.add(dbm_i); + } + dbmCnt = allDbmSet.size(); + int untimedStateCnt = prjStateZoneSet.size(); + + System.out.println("---> # of untimed states = " + untimedStateCnt + + "\n" + "---> # of unique zones = " + Zone1.uniqueCache.size() + + "\n" + "---> # of unique enabled arrays = " + + Zone1.enabledArrayCache.size() + "\n" + + "---> # of unique DBMs = " + dbmCnt + "\n"); + + System.out.println("SUMMARY: # LPN transition firings: " + + tranFiringCnt + ", max_stack_depth: " + max_stack_depth); + } + + private static void search_dfs_abstraction(StateGraph[] lpnList, State[] initStateArray) { + System.out.println("---> Calling timedProject.findsg_dfs"); + + int arraySize = lpnList.length; + int max_stack_depth = 0; + long peakTotalMem = 0; + long peakUsedMem = 0; + boolean failure = false; + boolean useMDT = false; // switch between prjStateSet and reachSet fto store states + + /* + * Create objects to hold state space information + */ + HashMap prjStateSet = null; + mdtNode reachSet = null; + // TODO: I build both to eliminate warnings. It thinks it may be using a null variable below otherwise + // it cannot work out the correllation with useMDT. + //if(useMDT==true) + reachSet = new mdtNode(); + //else + prjStateSet = new HashMap(); + + // /* + // * Compute the set of input transitions for each module + // */ + // HashSet[] inputTranSetArray = new HashSet[arraySize]; + // for(int i = 0; i curInputTranSet = new HashSet(); + // HashSet inputVarSet = curLpn.getInputs(); + // for(int other_i = 0; other_i assignedVarSet = other_tran.getAssignedVar(); + // for(String assignedVar : assignedVarSet) + // if(inputVarSet.contains(assignedVar)==true) { + // curInputTranSet.add(other_tran); + // break; + // } + // } + // } + // inputTranSetArray[i] = curInputTranSet; + // } + // + // for(int i = 0; i)inputTranSetArray[i]) { + // System.out.print(tran.getFullLabel() + " "); + // } + // System.out.println("---------------------"); + // } + + /* + * Compute the untimed enabled transition arrays in the initial state + */ + LpnTranList[] initEnabledArray = new LpnTranList[arraySize]; + ArrayList> enabledArrayList = new ArrayList>(); + for (int i = 0; i < arraySize; i++) { + LpnTranList tmp = lpnList[i].getEnabled(initStateArray[i]); + initEnabledArray[i] = tmp; + enabledArrayList.add(i, tmp); + } + + /* + * Compute the initial zone, project the zone to each module, and + * enlarge the zone corresponding to the zone projection. + */ + Zone1 initZone = new Zone1(); + initZone.initialize(initEnabledArray); + + /* + * Compute the timed enabled transitions in the initial state + */ + LpnTranList initTimedEnabled = new LpnTranList(); + for (int i = 0; i < arraySize; i++) { + for (Transition tran : initEnabledArray[i]) + if (initZone.checkTiming(tran) == true) + initTimedEnabled.addLast(tran); + } + + if (initTimedEnabled.size() == 0) { + System.err + .println("---> ERROR: Verification failed: deadlock in the initial state."); + failure = true; + return; + } + + /* + * Initializing the stacks needed for search. + */ + Stack stateStack = new Stack(); + Stack zone1Stack = new Stack(); + Stack posetStack = new Stack(); + Stack lpnTranStack = new Stack(); + + stateStack.push(initStateArray); + zone1Stack.push(initZone); + posetStack.push(null); + lpnTranStack.push(initTimedEnabled); + + PrjState initPrjState = new PrjState(initStateArray); + if (useMDT==true) + reachSet.merge(initStateArray, initZone.getDbm(), 0); + else + prjStateSet.put(initPrjState, initZone.getDbm()); + + int tranFiringCnt = 0; + int iterations = 0; + + /* + * Main search loop. + */ + main_while_loop: while (failure == false && stateStack.empty() == false) { + iterations++; + + long curTotalMem = Runtime.getRuntime().totalMemory(); + long curUsedMem = Runtime.getRuntime().totalMemory() + - Runtime.getRuntime().freeMemory(); + + if (curTotalMem > peakTotalMem) + peakTotalMem = curTotalMem; + + if (curUsedMem > peakUsedMem) + peakUsedMem = curUsedMem; + + // if(iterations == 200) System.exit(0); + if (iterations % 2000 == 0) { + System.out.println("---> #iteration " + iterations + + "> # LPN transition firings: " + tranFiringCnt + + ", # of prjStates: " + (useMDT ? reachSet.pathCount() : prjStateSet.size()) + + ", # of zones: " + Zone1.uniqueCache.size() + + ", max_stack_depth: " + max_stack_depth + + " used memory: " + (float) curUsedMem / 1000000 + + " free memory: " + + (float) Runtime.getRuntime().freeMemory() / 1000000); + } + + if (stateStack.size() > max_stack_depth) { + max_stack_depth = stateStack.size(); + } + + State[] curStateArray = stateStack.peek(); + Zone1 curZone = zone1Stack.peek(); + PrjState curPrjState = new PrjState(curStateArray); + DBM curExistingDbm = null; + if (useMDT==true) + curExistingDbm = reachSet.getDbm(curStateArray, 0); + else + curExistingDbm = prjStateSet.get(curPrjState); + boolean curZoneUseless = (curZone.getDbm().equals(curExistingDbm) == false && curZone.getDbm().subset(curExistingDbm) == true); + Poset curPoset = posetStack.peek(); + LpnTranList curTimedEnabled = lpnTranStack.peek(); + + if (curTimedEnabled.size() == 0 || curZoneUseless==true) { + stateStack.pop(); + zone1Stack.pop(); + posetStack.pop(); + lpnTranStack.pop(); + continue main_while_loop; + } + + Transition firedTran = curTimedEnabled.removeLast(); + +// for(int i = 0; i < curStateArray.length; i++) +// System.out.print(curStateArray[i] + ", "); +// System.out.println(); +// System.out.println("firedTran " + firedTran.getFullLabel()); + + //int curIndex = firedTran.getLpn().getLpnIndex(); + // TODO: fire has been moved to StateGraph. + State[] nextStateArray = null; //firedTran.fire(lpnList, curStateArray); + tranFiringCnt++; + + LpnTranList[] curEnabledArray = new LpnTranList[arraySize]; + LpnTranList[] nextEnabledArray = new LpnTranList[arraySize]; + for (int i = 0; i < arraySize; i++) { + StateGraph lpn_tmp = lpnList[i]; + LpnTranList enabledList = null; + enabledList = lpn_tmp.getEnabled(curStateArray[i]); + curEnabledArray[i] = enabledList; + // TODO: have to cut below because NULL + //enabledList = lpn_tmp.getEnabled(nextStateArray[i]); + //nextEnabledArray[i] = enabledList.clone(); + } + + // System.out.println(curZone); + // System.out.println("\nfiredTran = " + firedTran.getFullLabel() + + // "\n"); + Poset nextPoset = null; + if (curPoset == null) { + nextPoset = new Poset(); + nextPoset.initialize(firedTran, nextEnabledArray); + } else { + nextPoset = curPoset.update(firedTran, curEnabledArray, + nextEnabledArray); + } + + // System.out.println(nextPoset); + + Zone1 nextZone = curZone.update(firedTran, nextEnabledArray); + // nextZone.enlarge(nextEnabledArray, inputTranSetArray); + // Zone1 pZone = new Zone1(nextPoset, nextEnabledArray); + + // System.out.println(nextZone + + // "\n---------------------------------\n");// + pZone + + // "\n========================================\n"); + + // /* + // * Check if nextZone already exists in the cache. If so, get the + // existing copy. + // */ + // Zone1 newNextZone1 = Zone1.uniqueCache.get(nextZone); + // if(newNextZone1 == null) { + // Zone1.uniqueCache.put(nextZone, nextZone); + // System.out.println(nextZone + "\n " + Zone1.uniqueCache.size() + + // "\n---------------------------------\n"); + // } + // else { + // nextZone = newNextZone1; + // } + + /* + * Compute the timed enabled transitions w.r.t nextZone. + */ + LpnTranList nextTimedEnabled = new LpnTranList(); + for (int i = 0; i < arraySize; i++) { + LpnTranList tmp = nextEnabledArray[i]; + for (Transition tran : tmp) { + if (nextZone.checkTiming(tran) == true) + nextTimedEnabled.addLast(tran); + } + } + + /* + * Check disabling error + */ + // TODO: disablingError was moved to StateGraph. + //Transition disabledTran = null;//firedTran.disablingError(curTimedEnabled, + // nextTimedEnabled); + // TODO: DEAD CODE + /* + if (disabledTran != null) { + System.out.println("---> Disabling Error: " + + disabledTran.getFullLabel() + " is disabled by " + + firedTran.getFullLabel()); + + System.out.println("Current state:"); + for (int ii = 0; ii < arraySize; ii++) { + System.out.println("module " + lpnList[ii].getLpn().getLabel()); + System.out.println(curStateArray[ii]); + System.out.println("Enabled set: " + curEnabledArray[ii]); + } + System.out.println("Timed enabled transitions: " + + curTimedEnabled); + + System.out.println("======================\nNext state:"); + for (int ii = 0; ii < arraySize; ii++) { + System.out.println("module " + lpnList[ii].getLpn().getLabel()); + System.out.println(nextStateArray[ii]); + System.out.println("Enabled set: " + nextEnabledArray[ii]); + } + System.out.println("Timed enabled transitions: " + + nextTimedEnabled); + + System.out.println(); + + failure = true; + break main_while_loop; + } + */ + + /* + * Check deadlock. + */ + if (nextTimedEnabled.size() == 0) { + System.out + .println("---> ERROR: Verification failed: deadlock."); + for (int ii = 0; ii < arraySize; ii++) { + System.out.println("module " + lpnList[ii].getLpn().getLabel()); + //System.out.println(nextStateArray[ii]); + System.out.println("Enabled set: " + nextEnabledArray[ii]); + } + System.out.println("Zone: " + nextZone); + failure = true; + continue main_while_loop; + } + + /* + * Add the new timed state, and check if this is a new timed state. + * Zone subset relation is checked to reduce redundant zones. + */ + boolean isNew = false; + + PrjState nextPrjState = new PrjState(nextStateArray); + DBM existingDBM = null; + if (useMDT==true) + existingDBM = reachSet.getDbm(nextStateArray, 0); + else + existingDBM = prjStateSet.get(nextPrjState); + if (existingDBM == null) { + if (useMDT==true) + reachSet.merge(nextStateArray, nextZone.getDbm(), 0); + else + prjStateSet.put(nextPrjState, nextZone.getDbm()); + isNew = true; + } + else if (nextZone.getDbm().subset(existingDBM)==false) { + DBM newDbm = existingDBM.merge(nextZone.getDbm()); + Zone1 newNextZone = new Zone1(nextZone.getEnabledSet(), newDbm); + nextZone = newNextZone; + if (useMDT==true) + reachSet.merge(nextStateArray, newDbm, 0); + else + prjStateSet.put(nextPrjState, newDbm); + isNew = true; + } + + if (isNew == true) { + stateStack.push(nextStateArray); + zone1Stack.push(nextZone); + posetStack.push(nextPoset); + lpnTranStack.push(nextTimedEnabled); + } + } + + System.out.println("SUMMARY:\n" + + "# LPN transition firings: " + + tranFiringCnt + ", # of prjStates found: " + (useMDT ? reachSet.pathCount() : prjStateSet.size()) + ", " + + ", max_stack_depth: " + + max_stack_depth + "\n" + + "---> # of unique zones = " + + Zone1.uniqueCache.size() + "\n" + + "---> # of unique enabled arrays = " + + Zone1.enabledArrayCache.size() + "\n" + + "---> # of unique DBMs = " + (useMDT ? reachSet.pathCount() : prjStateSet.size()) + "\n" + + "---> # of unique timeSeps = " + Zone1.timeSepTbl.size() + + "\n"); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/TimingState.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/TimingState.java new file mode 100644 index 000000000..e2362cecf --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/TimingState.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.TimingAnalysis; + +import edu.utah.ece.async.lema.verification.platu.TimingAnalysis.Zone1; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class TimingState { + + State state; + Zone1 zone; + int index; + + public TimingState() { + state = null; + zone = null; + index = -1; + } + + public TimingState(State newState, Zone1 newZone) { + state = newState; + this.zone = newZone; + index = -1; + } + + public TimingState(TimingState other) { + this.state = other.state; + this.zone = other.zone; + this.index = other.index; + } + + public void setIndex(int idx) { + this.index = idx; + } + + public int getIndex() { + return this.index; + } + + + @Override + public String toString() { + return state.toString() + "\n" + zone.toString() + "\n"; + } + + @Override + public boolean equals(Object other) { + TimingState otherState = (TimingState)other; + + if(this.state != otherState.state) + return false; + + if((this.zone==null && otherState.zone!=null) || (this.zone!=null && otherState.zone==null)) + return false; + + if(this.zone != null && otherState.zone != null && this.zone.equals(otherState.zone)==false) + return false; + + return true; + } + + @Override + public int hashCode() { + if(this.zone == null) + return state.hashCode(); + + return state.hashCode() ^ this.zone.hashCode(); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/Zone1.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/Zone1.java new file mode 100644 index 000000000..7aff32812 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/Zone1.java @@ -0,0 +1,632 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.TimingAnalysis; + +import java.util.*; + +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.platuLpn.*; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Zone1 { + public static final int INFINITY = edu.utah.ece.async.lema.verification.platu.common.Common.INFINITY; + + public static HashMap uniqueCache = null; + public static HashMap enabledArrayCache = null; + //public static HashMap dbmCache = null; + public static HashMap, LinkedList> timeSepTbl = null; + + DualHashMap enabledSet; + private DBM dbm; + //HashMap, Integer> timeSep; + + public Zone1() { + if(Zone1.uniqueCache==null) + Zone1.uniqueCache = new HashMap(); + if(Zone1.enabledArrayCache==null) + Zone1.enabledArrayCache = new HashMap(); + if(Zone1.timeSepTbl==null) + Zone1.timeSepTbl = new HashMap, LinkedList>(); + + enabledSet = null; + dbm = null; + //timeSep = null; + } + + public Zone1(Object other) { + Zone1 otherZone = (Zone1)other; + enabledSet = otherZone.enabledSet; + dbm = otherZone.dbm; + //timeSep = otherZone.timeSep; + } + + public Zone1(DualHashMap newEnabledSet, DBM newDbm) { + this.enabledSet = newEnabledSet; + this.dbm = newDbm; + } + + /* + * Generate a new zone from a poset. + */ + public Zone1(Poset curPoset, LpnTranList[] nextEnabledArray) { + this.enabledSet = new DualHashMap(); + int arraySize = nextEnabledArray.length; + int lpnTranCnt = 0; + for(int i = 0; i < arraySize; i++) { + for(Transition tran : nextEnabledArray[i]) { + this.enabledSet.insert(tran, lpnTranCnt+1); + lpnTranCnt++; + } + } + + /* + * Caching the enabled transition set. + */ + DualHashMap newEnabledSet = Zone1.enabledArrayCache.get(this.enabledSet); + if (newEnabledSet == null) + Zone1.enabledArrayCache.put(this.enabledSet, this.enabledSet); + else + this.enabledSet = newEnabledSet; + + this.dbm = new DBM(lpnTranCnt + 1); + + for (int i = 1; i <= lpnTranCnt; i++) { + Transition tran_i = this.enabledSet.getKey(i); + // TODO: Get the upper bound of our LPN delay + //this.dbm.assign(0, i, tran_i.getDelayUB()); + this.dbm.assign(i, 0, 0); + for (int j = 1; j <= lpnTranCnt; j++) { + Transition tran_j = this.enabledSet.getKey(j); + if(tran_i == tran_j) + continue; + if(curPoset != null) + this.dbm.assign(i, j, curPoset.getTimeSep(tran_i, tran_j)); + else + this.dbm.assign(i, j, 0); + } + } + this.dbm.canonicalize(); + + /* + * Zone normalization + */ + int newLpnTranCnt = this.enabledSet.size(); + for(int i = 1; i <= newLpnTranCnt; i++) { + //Transition tran = this.enabledSet.getKey(i); + // TODO: Get the upper/lower bound of our LPN delay + int premax = 3;//tran.getDelayUB()==INFINITY ? tran.getDelayLB() : tran.getDelayUB(); + int delta = this.dbm.value(i, 0) + premax; + if(delta >= 0) + continue; + for(int j = 0; j <= newLpnTranCnt; j++) { + if(i == j) + continue; + int new_ij = this.dbm.value(i, j) - delta; + this.dbm.assign(i, j, new_ij); + int new_ji = this.dbm.value(j, i) + delta; + this.dbm.assign(j, i, new_ji); + } + } + + LinkedList fixup = new LinkedList(); + for(int i = 1; i <= newLpnTranCnt; i++) { + //Transition tran_i = this.enabledSet.getKey(i); + // TODO: Get the upper/lower bound of our LPN delay + int premax_i = 3; //tran_i.getDelayUB()==INFINITY ? tran_i.getDelayLB() : tran_i.getDelayUB(); + if(this.dbm.value(0, i) > premax_i) { + int t = premax_i; + for(int j = 1; j <= newLpnTranCnt; j++) { + //Transition tran_j = this.enabledSet.getKey(j); + // TODO: Get the upper/lower bound of our LPN delay + int premax_j = 3; //tran_j.getDelayUB()==INFINITY ? tran_j.getDelayLB() : tran_j.getDelayUB(); + int min = this.dbm.value(0, j) < premax_j ? this.dbm.value(0, j) : premax_j; + int new_max = min - this.dbm.value(i, j); + if(new_max > t) + t = new_max; + } + if(t < this.dbm.value(0, i)) { + fixup.addLast(i); + this.dbm.assign(0, i, t); + } + } + } + + if(fixup.size() > 0) { + for(int i = 1; i <= newLpnTranCnt; i++) { + for(Integer j : fixup) { + if(i == j) + continue; + int val_i0 = this.dbm.value(i, 0); + int val_0j = this.dbm.value(0, j); + if(val_i0 + val_0j < this.dbm.value(i, j)) + this.dbm.assign(i, j, val_0j + val_0j); + } + } + } + } + + + @Override + public Zone1 clone() { + return null; + } + + /** + * Size of key set (width of DBM including t0). + * + * @return + */ + public int size() { + return this.enabledSet.size(); + } + + /** + * Initialize zone. Input is a list of lists of LPNTran + * + * @param z + * @param initEnSet + */ + final public void initialize(LpnTranList[] initEnabledArray) { + this.enabledSet = new DualHashMap(); + int arraySize = initEnabledArray.length; + int lpnTranCnt = 0; + for(int i = 0; i < arraySize; i++) { + for(Transition tran : initEnabledArray[i]) { + this.enabledSet.insert(tran, lpnTranCnt+1); + lpnTranCnt++; + } + } + + /* + * Caching the enabled transition set. + */ + DualHashMap newEnabledSet = Zone1.enabledArrayCache.get(this.enabledSet); + if(newEnabledSet==null) + Zone1.enabledArrayCache.put(this.enabledSet, this.enabledSet); + else + this.enabledSet = newEnabledSet; + + this.dbm = new DBM(lpnTranCnt+1); + + for(int y = 1; y <= lpnTranCnt; y++) { + //Transition curTran = this.enabledSet.getKey(y); + // TODO: Get the upper/lower bound of our LPN delay + //this.dbm.assign(0, y, curTran.getDelayUB()); + } + } + + /** + * Call these functions. restrict(zone, fired, lowerBound); + * zone.recanonicalize(); zone.project(fired); allocate(newSet, zone); + * extend(newSet, nmnSet, zone); advanceTime(enSet, ubSet, zone); + * zone.recanonicalize(); + * + * @param firedLocalTran + * @param NEXT + * @param CURRENT + * @param nextEnabledList + * @param curModuleTranSet + */ + public Zone1 update(Transition firedTran, LpnTranList[] nextEnabledArray) { + Zone1 newZone = new Zone1(); + + newZone.enabledSet = new DualHashMap(); + int arraySize = nextEnabledArray.length; + int nextLpnTranCnt = 0; + for(int i = 0; i < arraySize; i++) { + for(Transition tran : nextEnabledArray[i]) { + newZone.enabledSet.insert(tran, nextLpnTranCnt+1); + nextLpnTranCnt++; + } + } + + /* + * Caching the enabled transition set. + */ + DualHashMap newEnabledSet = Zone1.enabledArrayCache.get(newZone.enabledSet); + if(newEnabledSet==null) + Zone1.enabledArrayCache.put(newZone.enabledSet, newZone.enabledSet); + else + newZone.enabledSet = newEnabledSet; + + /* + * Update DBM of this zone. + */ + newZone.dbm = new DBM(nextLpnTranCnt+1); + + DBM curDbmCopy = new DBM(this.dbm); + + /* + * Restrict zone w.r.t firedTran, and canonialize it. + */ + int new_x = this.enabledSet.getValue(firedTran); + // TODO: Get the upper/lower bound of our LPN delay + //curDbmCopy.restrict(new_x, firedTran.getDelayLB()); + curDbmCopy.canonicalize(); + + //System.out.println("update 1 \n" + curDbmCopy); + + /* + * Copy timing information of transitions enabled in both current and new states from tmp_dbm + * to newZone + */ + int curLpnTranCnt = this.enabledSet.size(); + for(int x = 0; x <= curLpnTranCnt; x++) { + new_x = 0; + if(x>0) { + Transition tran_x = this.enabledSet.getKey(x); + if(newZone.enabledSet.containsKey(tran_x) == false || tran_x==firedTran) + continue; + new_x = newZone.enabledSet.getValue(tran_x); + } + for(int y = 0; y <= curLpnTranCnt; y++) { + int new_y = 0; + if(y > 0) { + Transition tran_y = this.enabledSet.getKey(y); + if(newZone.enabledSet.containsKey(tran_y)==false || tran_y==firedTran) + continue; + new_y = newZone.enabledSet.getValue(tran_y); + } + //System.out.println("x, y = " +x+", " +y + "; new_x, new_y = " + new_x +", " + new_y + ", val(x, y) = " + tmp_dbm.value(x, y)); + newZone.dbm.assign(new_x, new_y, curDbmCopy.value(x, y)); + } + } + + //System.out.println("update 2 \n" + newZone.dbm); + + + /* + * For every enabled transitions in the nextState, advance its timer to DelayUB, and canonicalize. + */ + LinkedList newTranList = new LinkedList(); + int newLpnTranCnt = newZone.enabledSet.size(); + for(int y = 1; y <= newLpnTranCnt; y++) { + Transition tran_y = newZone.enabledSet.getKey(y); + + if(this.enabledSet.containsKey(tran_y)==false || tran_y == firedTran) { + newTranList.addLast(tran_y); + } + } + + /* + * Adjust timing constraints between the enabled transitions in the current state and + * those that are newly enabled in the next state. + */ + curLpnTranCnt = this.enabledSet.size(); + for(Transition newTran : newTranList) { + int new_i = newZone.enabledSet.getValue(newTran); + for(int j = 1; j <= curLpnTranCnt; j++) { + Transition tran_j = this.enabledSet.getKey(j); + if(newZone.enabledSet.containsKey(tran_j) == false) + continue; + int new_j = newZone.enabledSet.getValue(tran_j); + int val_0j = newZone.dbm.value(0, new_j); + newZone.dbm.assign(new_i, new_j, val_0j); + int val_j0 = newZone.dbm.value(new_j, 0); + newZone.dbm.assign(new_j, new_i, val_j0); + } + } + + /* + * For every enabled transitions in the nextState, advance its timer to DelayUB, and canonicalize. + */ + HashMap newTranSet = new HashMap(); + for(int y = 1; y <= newLpnTranCnt; y++) { + Transition tran_y = newZone.enabledSet.getKey(y); + // TODO: Get the upper/lower bound of our LPN delay + //newZone.dbm.assign(0, y, tran_y.getDelayUB()); + newTranSet.put(tran_y, y); + if(this.enabledSet.containsKey(tran_y)==false || tran_y == firedTran) { + newTranList.addLast(tran_y); + } + } + + //System.out.println("update 3 \n" + newZone.dbm); + + newZone.dbm.canonicalize(); + + //System.out.println("update 4 \n" + newZone.dbm); + + /* + * Zone normalization + */ + for(int i = 1; i <= newLpnTranCnt; i++) { + //Transition tran = newZone.enabledSet.getKey(i); + // TODO: Get the upper/lower bound of our LPN delay + int premax = 3; //tran.getDelayUB()==INFINITY ? tran.getDelayLB() : tran.getDelayUB(); + int delta = newZone.dbm.value(i, 0) + premax; + if(delta >= 0) + continue; + for(int j = 0; j <= newLpnTranCnt; j++) { + if(i == j) + continue; + int new_ij = newZone.dbm.value(i, j) - delta; + newZone.dbm.assign(i, j, new_ij); + int new_ji = newZone.dbm.value(j, i) + delta; + newZone.dbm.assign(j, i, new_ji); + } + } + + LinkedList fixup = new LinkedList(); + for(int i = 1; i <= newLpnTranCnt; i++) { + //Transition tran_i = newZone.enabledSet.getKey(i); + // TODO: Get the upper/lower bound of our LPN delay + int premax_i = 3; //tran_i.getDelayUB()==INFINITY ? tran_i.getDelayLB() : tran_i.getDelayUB(); + if(newZone.dbm.value(0, i) > premax_i) { + int t = premax_i; + for(int j = 1; j <= newLpnTranCnt; j++) { + //Transition tran_j = newZone.enabledSet.getKey(j); + // TODO: Get the upper/lower bound of our LPN delay + int premax_j = 3; //tran_j.getDelayUB()==INFINITY ? tran_j.getDelayLB() : tran_j.getDelayUB(); + int min = newZone.dbm.value(0, j) < premax_j ? newZone.dbm.value(0, j) : premax_j; + int new_max = min - newZone.dbm.value(i, j); + if(new_max > t) + t = new_max; + } + if(t < newZone.dbm.value(0, i)) { + fixup.addLast(i); + newZone.dbm.assign(0, i, t); + } + } + } + + if(fixup.size() > 0) { + for(int i = 1; i <= newLpnTranCnt; i++) { + for(Integer j : fixup) { + if(i == j) + continue; + int val_i0 = newZone.dbm.value(i, 0); + int val_0j = newZone.dbm.value(0, j); + if(val_i0 + val_0j < newZone.dbm.value(i, j)) + newZone.dbm.assign(i, j, val_0j + val_0j); + } + } + } + + //System.out.println("update 5 \n" + newZone.dbm); + + return newZone; + } + + public Zone1[] split(LpnTranList[] enabledArray) { + int arraySize = enabledArray.length; + Zone1[] subZoneArray = new Zone1[arraySize]; + + //HashMap, Integer> timeSepSet = new HashMap, Integer>(); + + /* + * Create the local zones and initialize their local enabledSet. + */ + for(int curIdx = 0; curIdx < arraySize; curIdx++) { + if(enabledArray[curIdx]==null || enabledArray[curIdx].size()==0) { + subZoneArray[curIdx] = null; + continue; + } + + Zone1 curSubZone = new Zone1(); + curSubZone.enabledSet = new DualHashMap(); + int tranIdx = 1; + //Transition curFirstTran = enabledArray[curIdx].getFirst(); + for(Transition curTran : enabledArray[curIdx]) + curSubZone.enabledSet.insert(curTran, tranIdx++); + + /* + * Copy the cell values for the local zones from the global zone. + */ + int localDim = curSubZone.enabledSet.size(); + curSubZone.dbm = new DBM(localDim + 1); + for(int x = 0; x <= localDim; x++) { + int g_x = 0; + if(x > 0) { + Transition x_tran = curSubZone.enabledSet.getKey(x); + g_x = this.enabledSet.getValue(x_tran); + } + for(int y = 0; y <= localDim; y++) { + if(x==y) + continue; + + int g_y = 0; + if(y > 0) { + Transition y_tran = curSubZone.enabledSet.getKey(y); + g_y = this.enabledSet.getValue(y_tran); + } + + curSubZone.dbm.assign(x, y, this.dbm.value(g_x, g_y)); + } + } + + /* + * Generate the time separations between this and other modules. + */ +// for(int otherIdx = 0; otherIdx < arraySize; otherIdx++) { +// if(curIdx == otherIdx || enabledArray[otherIdx] == null || enabledArray[otherIdx].size()==0) +// continue; +// +// LPNTran otherFirstTran = enabledArray[otherIdx].getFirst(); +// +// if(curSubZone.timeSep==null) +// curSubZone.timeSep = new HashMap, Integer>(); +// +// int curFirstTranIdx = this.enabledSet.getValue(curFirstTran); +// int otherFirstTranIdx = this.enabledSet.getValue(otherFirstTran); +// LinkedList cur2otherPair = new LinkedList(); +// cur2otherPair.addFirst(curFirstTran); +// cur2otherPair.addLast(otherFirstTran); +// curSubZone.timeSep.put(cur2otherPair, this.dbm.value(otherFirstTranIdx, curFirstTranIdx)); +// LinkedList other2curPair = new LinkedList(); +// other2curPair.addFirst(otherFirstTran); +// other2curPair.addLast(curFirstTran); +// curSubZone.timeSep.put(other2curPair, this.dbm.value(curFirstTranIdx, otherFirstTranIdx)); +// +// timeSepSet.put(cur2otherPair, this.dbm.value(otherFirstTranIdx, curFirstTranIdx)); +// timeSepSet.put(other2curPair, this.dbm.value(curFirstTranIdx, otherFirstTranIdx)); +// } + + subZoneArray[curIdx] = curSubZone; + } + + + return subZoneArray; + } + + public LinkedList enlarge(LpnTranList[] enabledArray) { + //System.out.println(this + "\n"); + + int arraySize = enabledArray.length; + DBM dbmCopy = new DBM(this.dbm); + this.dbm = dbmCopy; + + LinkedList timeSepSet = new LinkedList(); + + for(int i = 0; i < arraySize; i++) { + for(int j = 0; j < arraySize; j++) { + if(i == j) + continue; + + //boolean first_j = true; + for(Transition tran_i : enabledArray[i]) { + int m_i = this.enabledSet.getValue(tran_i); + for(Transition tran_j : enabledArray[j]) { + int m_j = this.enabledSet.getValue(tran_j); +// if(first_j) { +// first_j = false; +// timeSepSet.addLast(this.dbm.value(m_i, m_j)); +// continue; +// } + + + //System.out.println(tran_i.getFullLabel() + " " + tran_j.getFullLabel()); + this.dbm.assign(m_i, m_j, INFINITY); + this.dbm.assign(m_j, m_i, INFINITY); + } + } + } + } + + //System.out.println(this.dbm + "-----------------------"); + //System.out.println(this.dbm + "\n"); + this.dbm.canonicalize(); + //System.out.println(this.dbm + "xxxxxxxxxxxxxxxxxxxxxxx\n"); + + if(timeSepSet.size() > 0) { + LinkedList newTimeSepSet = Zone1.timeSepTbl.get(timeSepSet); + if(newTimeSepSet == null) + Zone1.timeSepTbl.put(timeSepSet, timeSepSet); + else + timeSepSet = newTimeSepSet; + } + return timeSepSet; + } + + public int[] signature() { + return this.dbm.signature(); + } + + /** + * Set (0,t) to the upper bound of t, for all t. + * + * @param initEnSet + */ + public boolean checkTiming(Transition curTran) { + // TODO: Get the upper/lower bound of our LPN delay + int curTranDelayLB = 3; // curTran.getDelayLB(); + if (curTranDelayLB == 0) { + return true; + } + + int x = this.enabledSet.getValue(curTran); + Integer curTimingUB = this.dbm.value(0, x); + return curTranDelayLB <= curTimingUB; + } + + /* + * Check if the this zone is a subset of the other zone. + */ + public boolean subset(Zone1 other) { + if(this.enabledSet != other.enabledSet) + return false; + + return this.dbm.subset(other.dbm); + } + + public DualHashMap getEnabledSet() { + return this.enabledSet; + } + + public DBM getDbm() { + return this.dbm; + } + + @Override + public int hashCode() { + //if(this.timeSep==null) + return Integer.rotateLeft(this.enabledSet.hashCode(), 11) ^ Integer.rotateLeft(this.dbm.hashCode(), 7); + + //return Integer.rotateLeft(this.enabledSet.hashCode(), 11) ^ Integer.rotateLeft(this.dbm.hashCode(), 7) ^ Integer.rotateLeft(this.timeSep.hashCode(), 19); + } + + @Override + public boolean equals(Object other) { + Zone1 otherZone = (Zone1)other; + //if(this.enabledSet.equals(otherZone.enabledSet)==false) + if(this.enabledSet != otherZone.enabledSet) + return false; + +// System.out.println("this zone : " + this.dbm); +// System.out.println("\nother zone : " + otherZone.dbm + "\n ================================="); + + //if(this.dbm.equals(otherZone.dbm)==false) + if(this.dbm != otherZone.dbm) + return false; + +// if(this.timeSep == null && otherZone.timeSep == null) +// return true; +// +// if((this.timeSep == null && otherZone.timeSep != null) || (this.timeSep != null && otherZone.timeSep == null)) +// return false; +// +// if(this.timeSep.equals(otherZone.timeSep) == false) +// return false; + + return true; + } + + @Override + public String toString() { + String ret = new String(); + ret = "\tt0"; + for(int i = 1; i <= this.enabledSet.size(); i++) + ret += "\t" + this.enabledSet.getKey(i).getFullLabel(); + + String timeSepConstraints = new String(); + +// if(this.timeSep != null) { +// Set> tranPairs = this.timeSep.keySet(); +// for(LinkedList tranPair : tranPairs) +// timeSepConstraints += "(" + tranPair.getFirst().getFullLabel() + ", " + tranPair.getLast().getFullLabel() + ", " + this.timeSep.get(tranPair)+"), "; +// } +// else +// timeSepConstraints = "timeSep = null"; + + + return ret + "\n\n" + this.dbm.toString() + timeSepConstraints +"\n"; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/mdtNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/mdtNode.java new file mode 100644 index 000000000..b1faaec86 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/TimingAnalysis/mdtNode.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.TimingAnalysis; + +import java.util.*; + +import edu.utah.ece.async.lema.verification.platu.TimingAnalysis.DBM; +import edu.utah.ece.async.lema.verification.platu.stategraph.*; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class mdtNode { + static public int totalStates = 0; + private HashMap nodeMap; + private LinkedList dbmSet; + + public mdtNode() { + this.nodeMap = null; + this.dbmSet = null; + } + + public boolean add(State[] stateArray, DBM dbm, int level) { + boolean isNew = false; + + if(level == stateArray.length) { + if(this.dbmSet == null) { + this.dbmSet = new LinkedList(); + this.dbmSet.addLast(dbm); + isNew = true; + } + else { + boolean isSubDbm = false; + LinkedList subDbms = new LinkedList(); + for(DBM oldDbm : this.dbmSet) { + if(isSubDbm==false && dbm.subset(oldDbm)==true) + isSubDbm = true; + else if (oldDbm.subset(dbm)==true) + subDbms.addLast(oldDbm); + } + + for (DBM subDbm : subDbms) + this.dbmSet.remove(subDbm); + + if (isSubDbm==false) { + this.dbmSet.addLast(dbm); + isNew = true; + } + else + isNew = false; + } + return isNew; + } + + State curState = stateArray[level]; + + if(this.nodeMap == null) + this.nodeMap = new HashMap(); + + mdtNode nextNode = this.nodeMap.get(curState); + if(nextNode == null) { + nextNode = new mdtNode(); + nextNode.add(stateArray, dbm, level + 1); + this.nodeMap.put(curState, nextNode); + isNew = true; + } + else { + isNew = nextNode.add(stateArray, dbm, level+1); + } + + return isNew; + } + + public DBM merge(State[] stateArray, DBM dbm, int level) { + if(level == stateArray.length) { + if(this.dbmSet == null) { + this.dbmSet = new LinkedList(); + this.dbmSet.addLast(dbm); + totalStates++; + return dbm; + } + DBM existingDbm = this.dbmSet.removeFirst(); + DBM newDbm = dbm.merge(existingDbm); + this.dbmSet.addLast(newDbm); + return newDbm; + } + + State curState = stateArray[level]; + + if(this.nodeMap == null) + this.nodeMap = new HashMap(); + + int nextLevel = level+1; + mdtNode nextNode = this.nodeMap.get(curState); + if(nextNode == null) { + nextNode = new mdtNode(); + DBM newDbm = nextNode.merge(stateArray, dbm, nextLevel); + this.nodeMap.put(curState, nextNode); + return newDbm; + } + return nextNode.merge(stateArray, dbm, nextLevel); + } + + public DBM getDbm(State[] stateArray, int level) { + if (level == stateArray.length) + return this.dbmSet.getFirst(); + + State curSt = stateArray[level]; + mdtNode nextNode = this.nodeMap.get(curSt); + if (nextNode != null) + return nextNode.getDbm(stateArray, level+1); + return null; + } + + public boolean contains(State[] stateArray, DBM dbm, int level) { + if (level == stateArray.length) { + for(DBM existingDbm : this.dbmSet) { + System.out.println(dbm + "\n\n" + existingDbm); + if(dbm.subset(existingDbm)==true) + return true; + } + return false; + } + mdtNode nextNode = this.nodeMap.get(stateArray[level]); + if (nextNode == null) + return false; + System.out.println("level = " + level + ": " + stateArray[level] + " ---> " + nextNode); + return nextNode.contains(stateArray, dbm, level+1); + } + + public int pathCount() { + if (this.nodeMap != null) { + int count = 0; + Set stateSet = this.nodeMap.keySet(); + for (State curState : stateSet) { + mdtNode nextNode = this.nodeMap.get(curState); + count += nextNode.pathCount(); + } + return count; + } + + return this.dbmSet.size(); + } +} + diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/BinTreeTable.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/BinTreeTable.java new file mode 100644 index 000000000..623bc4ad2 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/BinTreeTable.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.common; + + +import edu.utah.ece.async.lema.verification.platu.BinaryTree.*; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class BinTreeTable extends SetIntTuple { + + BinaryTree StateTable = null; + int Size = 0; + + public BinTreeTable() { + this.StateTable = new BinaryTree(); + this.Size = 0; + } + + @Override + public int add(int[] IntArray) { + int newEle = StateTable.add(IntArray); + if(newEle != 0) + this.Size++; + return newEle==-1 ? 0 : 1; + } + + @Override + public boolean contains(int[] IntArray) { + return this.StateTable.contains(IntArray); + } + + @Override + public int size() { + return this.Size; + } + + @Override + public String stats() { + return "Element count = "+ this.StateTable.elementCount() + ", Tree node count = " + this.StateTable.nodeCount(); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/Common.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/Common.java new file mode 100644 index 000000000..147928437 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/Common.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.common; + +import java.io.Console; +import java.io.IOException; +import java.text.DecimalFormat; +import java.util.Collection; +import java.util.HashSet; +import java.util.TreeSet; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Definitions of commonly used constants, and functions for the entire project. + * + * @author ldtwo + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Common { + public static final int INFINITY = Integer.MAX_VALUE; + public static final int LPN_INT_MAX = Integer.MAX_VALUE; + public static final int LPN_INT_MIN = 0; + public static final DecimalFormat FLOAT=new DecimalFormat("00.000"); + public static final DecimalFormat LONG=new DecimalFormat("###,###,###,##0"); + + enum Verif_mode { verif_flat, verif_compositional }{} + enum Timing { timing_untimed, timing_timed }{} + + static public void pr(Object o) { + System.out.print(o); + } + + static public void prln(Object o) { + System.out.println(o); + } + + static public void pErr(Object o) { + System.err.println(o); + } + public static char getChar(){ + try { + return (char) System.in.read(); + } catch (IOException ex) { + Logger.getLogger(Common.class.getName()).log(Level.SEVERE, null, ex); + return ' '; + } + } + + public static boolean brk(Console con) { + char cmd = 'y'; + prln("Do you want to continue? y/n"); + while (true) { + // prln("simulate " + iterations++ + " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "); + if (con == null) { + break; + } + String line = con.readLine(); + if (line == null) { + pErr("line==null"); + } + else if (line.length() > 0) { + cmd = line.charAt(0); + if (cmd == 'n' || cmd == 'y') { + break; + } + prln("Wrong command. Try again"); + } else { + pErr("type 'y' OR 'n'"); + } + } + if (cmd == 'n') { + return false; + } + return true; + } + + public static Collection toList(int[] arr) { + TreeSet l = new TreeSet(); + for (int i : arr) { + l.add(i); + } + return l; + } + + public static Collection toList(T[] arr) { + HashSet l = new HashSet(); + for (T i : arr) { + l.add(i); + } + return l; + } + + public static int[] toArray(Collection set) { + int[] arr = new int[set.size()]; + int idx = 0; + for (int i : set) { + arr[idx++] = i; + } + return arr; + } + + static final public void forceGarbageCollection() { +// for (int i = 0; i < 5; i++) { +// try { +// Thread.sleep(15); +// garbage(i*1023); +// } catch (Exception ex) { +// Logger.getLogger(Common.class.getName()).log(Level.SEVERE, null, ex); +// } +// } + System.gc(); + for (int i = 0; i < 10; i++) { + try { + Thread.sleep(10); + } catch (Exception ex) { + Logger.getLogger(Common.class.getName()).log(Level.SEVERE, null, ex); + } + } + + } + + /** + * Call this to create garbage for the GC to collect. It will be more likely to + * free other garbage in the heap. THis will give more accurate initial memory + * readings. + * @return + */ + static final int garbage(int l) { + int[] nums = {1, 2, 43, 4, 4, 5, 23, 5, 5, 1, 2, 3, 4, 21, 34, 23, 4}; + int tot = 0; + String ss = ""; + for (int i : nums) { + for (int j : nums) { + for (int k : nums) { + String s = i + "" + j + "" + k+l; + ss += s; + s += s + s + i; + tot += s.length() + ss.length(); + } + } + } + + return tot; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/HashTable.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/HashTable.java new file mode 100644 index 000000000..910971003 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/HashTable.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.common; + +import java.util.*; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class HashTable extends SetIntTuple{ + + HashSet Table; + + public HashTable() { + this.Table = new HashSet(); + } + + @Override + public int add(int[] IntArray) { + boolean existing = this.Table.add(new IntArrayObj(IntArray)); + return existing ? 1 : 0; + } + + @Override + public boolean contains(int[] IntArray) { + return this.Table.contains(new IntArrayObj(IntArray)); + } + + @Override + public int size() { + return this.Table.size(); + } + + @Override + public String stats() { + return "States in state table: " + this.size(); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/IndexObjMap.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/IndexObjMap.java new file mode 100644 index 000000000..86efaf45d --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/IndexObjMap.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.common; + +import java.util.HashMap; + +import edu.utah.ece.async.lema.verification.platu.common.PlatuObj; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class IndexObjMap { + + protected HashMap uniqueObjTbl; + // TODO: (temp) str2ObjTbl is not used. +// protected HashMap str2ObjTbl; + protected HashMap idx2ObjTbl; + + public IndexObjMap() { + uniqueObjTbl = new HashMap(); +// str2ObjTbl = new HashMap(); + idx2ObjTbl = new HashMap(); + } + + public T add(T obj) { + T objCopy = uniqueObjTbl.get(obj); + if(objCopy != null) + return objCopy; + this.uniqueObjTbl.put(obj, obj); + +// String objLabel = obj.getLabel(); +// if(objLabel != null){ +// if(this.str2ObjTbl.containsKey(objLabel) == false) +// this.str2ObjTbl.put(obj.getLabel(), obj); +// else +// ;// Throw an exception +// } + + int idx = this.idx2ObjTbl.size(); + try { + if (idx > 2147483647) // Index is greater than the maximum number that int can represents. + throw new Exception(); + } catch (Exception e) { + System.out.println("Integer overflow."); + e.printStackTrace(); + } + obj.setIndex(idx); + this.idx2ObjTbl.put(idx, obj); + return obj; + } + +// public T get(String label) { +// return this.str2ObjTbl.get(label); +// } + + public T get(Integer index) { + return this.idx2ObjTbl.get(index); + } + + public int size() { + return this.uniqueObjTbl.size(); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/IntArrayObj.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/IntArrayObj.java new file mode 100644 index 000000000..bf6712a91 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/IntArrayObj.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.common; + + +import java.util.Arrays; + +import edu.utah.ece.async.lema.verification.platu.common.PlatuObj; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class IntArrayObj extends PlatuObj { + int index; + int[] IntArray; + + public IntArrayObj(int[] intArray) { + super(); + index = 0; + IntArray = intArray; + } + + public int[] toArray() { + return this.IntArray; + } + + @Override + public void setIndex(int Idx) { + this.index = Idx; + } + + @Override + public int getIndex() { + return this.index; + } + + @Override + public void setLabel(String lbl) {} + + @Override + public String getLabel() { return null; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(IntArray); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + IntArrayObj other = (IntArrayObj) obj; + if (!Arrays.equals(IntArray, other.IntArray)) + return false; + return true; + } + + @Override + public String toString() { + if(IntArray == null) + return "()"; + + String result = "("; + for(int i = 0; i < this.IntArray.length; i++) + result += this.IntArray[i] + ","; + result += ")"; + return result; + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/MddTable.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/MddTable.java new file mode 100644 index 000000000..add0bdc0b --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/MddTable.java @@ -0,0 +1,208 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.common; + + +import java.util.*; + +import edu.utah.ece.async.lema.verification.platu.MDD.*; +import edu.utah.ece.async.lema.verification.platu.main.Options; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class MddTable extends SetIntTuple { + + protected Mdd mddMgr = null; + mddNode ReachSet; + mddNode buffer; + + long nextMemUpBound; + int Size; + static boolean UseBuffer = true; + static boolean MDDBUF_MODE = true; + static int gcIntervalMin = 0; + + public MddTable(int TupleLength) { + mddMgr = new Mdd(TupleLength*4); + this.ReachSet = null; + if (UseBuffer == true) + this.buffer = Mdd.newNode(); + else + this.buffer = null; + + nextMemUpBound = 500000000; + this.Size = 0; + MddTable.MDDBUF_MODE = Options.getStateFormat() == "mddbuf"; + } + + @Override + public int add(int[] IntArray) { + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + + //int[] byteVec = toByteArray(IntArray); + int[] byteVec = MddTable.encode(IntArray); + + if(MddTable.UseBuffer == true && MddTable.MDDBUF_MODE==true) { + mddMgr.add(this.buffer, byteVec, false); + + boolean overThreshold = (Options.getMemUpperBound() - curUsedMem / 1000000) < 200; + if (overThreshold) { + mddMgr.compress(this.buffer); + if (this.ReachSet == null) + this.ReachSet = this.buffer; + else { + mddNode newReachSet = mddMgr.union(this.ReachSet, this.buffer); + if (newReachSet != this.ReachSet) { + mddMgr.remove(this.ReachSet); + this.ReachSet = newReachSet; + } + + if (newReachSet != this.ReachSet) { + mddMgr.remove(this.ReachSet); + this.ReachSet = newReachSet; + } + } + mddMgr.remove(this.buffer); + this.buffer = Mdd.newNode(); + Runtime.getRuntime().gc(); + MddTable.UseBuffer = false; + System.out.println("*** stop buffering"); + } + } + else { + if(this.ReachSet==null) + this.ReachSet = Mdd.newNode(); + mddMgr.add(this.ReachSet, byteVec, true); + if((Options.getMemUpperBound() - curUsedMem / 1000000) > 400) + MddTable.UseBuffer = true; + + } + + this.Size++; + return 0; + } + + @Override + public boolean contains(int[] IntArray) { + //int[] byteVec = toByteArray(IntArray); + int[] byteVec = MddTable.encode(IntArray); + + boolean existing = Mdd.contains(this.ReachSet, byteVec); + if (existing == true) + return true; + + if (this.buffer != null) + return Mdd.contains(this.buffer, byteVec); + + return false; + } + + @Override + public int size() { + return this.Size; + } + + @Override + public String stats() { + return "State count: " + this.Size + ", " + "MDD node count: " + this.mddMgr.nodeCnt(); + + } + + /* + * Utilities for search functions + */ + private static int[] toIntArray(int i) { + int[] charArray = new int[4]; + + int mask = 0x000000FF; + + for (int iter = 0; iter < 4; iter++) { + charArray[3 - iter] = (i & mask); + i = i >> 8; + } + return charArray; + } + + @SuppressWarnings("unused") + private static int[] toByteArray(int[] intVec) { + //System.out.println(Arrays.toString(intVec)); + int[] byteArray = new int[intVec.length*4]; + int offset = intVec.length; + int zeros = 0; + for (int i = 0; i < intVec.length; i++) { + int[] result = toIntArray(intVec[i]); + byteArray[i] = result[0]; + if(byteArray[i] == 0) + zeros++; + byteArray[offset+i] = result[1]; + byteArray[offset*2 + i] = result[2]; + byteArray[offset*3 + i] = result[3]; + } + + int firstNonZero = 0; + for(int i = 0; i < intVec.length*4; i++) + if(byteArray[i] != 0) { + firstNonZero = i; + break; + } + + int[] byteArray1 = byteArray; + if(firstNonZero > 0) { + int[] result = new int[intVec.length*4 - firstNonZero]; + for(int i = 0; i < result.length; i++) + result[i] = byteArray[i+firstNonZero]; + byteArray1 = result; + } + //System.out.println(Arrays.toString(byteArray1)+"\n-----------------------------------------------"); + return byteArray; + } + + private static int[] encode(int[] intVec) { + int[] codeArray = new int[intVec.length*2]; + int offset = intVec.length; + + for (int i = 0; i < intVec.length; i++) { + int remainder = intVec[i] & 0x000003FF; + int quotient = intVec[i] >> 10; + codeArray[i] = quotient; + codeArray[offset+i] = remainder; + } + +// System.out.println(Arrays.toString(intVec) + "\n--------------" + +// Arrays.toString(codeArray)); + return codeArray; + } + + @SuppressWarnings("unused") + private static HashSet decompose(int[] IntArray) { + HashSet result = new HashSet(); + + for (int i = 1; i < IntArray.length-1; i++) { + for (int ii = i+1; ii < IntArray.length; ii++) { + int[] tmp = new int[3]; + tmp[0] = IntArray[0]; + tmp[1] = IntArray[i]; + tmp[2] = IntArray[ii]; + result.add(new IntArrayObj(tmp)); + } + } + return result; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/Pair.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/Pair.java new file mode 100644 index 000000000..5d2f5c43d --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/Pair.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.common; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Pair { + LEFT left; + RIGHT right; + + public Pair(LEFT l, RIGHT r) { + this.left = l; + this.right = r; + } + + public LEFT getLeft() { + return this.left; + } + + public RIGHT getRight() { + return this.right; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((left == null) ? 0 : left.hashCode()); + result = prime * result + ((right == null) ? 0 : right.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + + if (obj == null) + return false; + + if (getClass() != obj.getClass()) + return false; + + Pair other = (Pair) obj; + if (left == null) { + if (other.left != null) + return false; + } + else if (!left.equals(other.left)) + return false; + + if (right == null) { + if (other.right != null) + return false; + } + else if (!right.equals(other.right)) + return false; + + return true; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/PlatuObj.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/PlatuObj.java new file mode 100644 index 000000000..259ea1df6 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/PlatuObj.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.common; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +abstract public class PlatuObj { + + abstract public void setIndex(int Idx); + + abstract public int getIndex(); + + abstract public void setLabel(String lbl); + + abstract public String getLabel(); +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/SetIntTuple.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/SetIntTuple.java new file mode 100644 index 000000000..b87cbb34e --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/common/SetIntTuple.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.common; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public abstract class SetIntTuple { + + abstract public int add(int[] IntArray); + + abstract public boolean contains(int[] IntArray); + + abstract public int size(); + + abstract public String stats(); +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/AddNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/AddNode.java new file mode 100644 index 000000000..648bbf768 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/AddNode.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class AddNode implements ExpressionNode{ + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public AddNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] statevector){ + return LeftOperand.evaluate(statevector) + RightOperand.evaluate(statevector); + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "+" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new AddNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/AndNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/AndNode.java new file mode 100644 index 000000000..f37377312 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/AndNode.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class AndNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public AndNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] statevector){ + if(LeftOperand.evaluate(statevector) == 0 || RightOperand.evaluate(statevector) == 0) + return 0; + + return 1; + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "&&" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new AndNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ArrayElement.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ArrayElement.java new file mode 100644 index 000000000..b7e6fcf8e --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ArrayElement.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ArrayElement extends VarNode{ + List indexVariables = null; + ArrayNode array = null; + + public ArrayElement(ArrayNode array, List indexVars){ + super(array.getName()); + this.array = array; + this.indexVariables = indexVars; + } + + public ArrayNode getArray(){ + return this.array; + } + + @Override + public int evaluate(int[] statevector){ + List indexValues = new ArrayList(this.indexVariables.size()); + for(ExpressionNode n : this.indexVariables){ + indexValues.add(n.evaluate(statevector)); + } + + return this.array.getElement(indexValues).evaluate(statevector); + } + + @Override + public void getVariables(HashSet variables){ + variables.add(this.array); + } + + @Override + public String toString(){ + String s = array.getName(); + for(ExpressionNode n : this.indexVariables){ + s += "[" + n.toString() + "]"; + } + + return s; + } + + @Override + public int getIndex(int[] stateVector){ + List indexValues = new ArrayList(this.indexVariables.size()); + for(ExpressionNode n : this.indexVariables){ + indexValues.add(n.evaluate(stateVector)); + } + + return this.array.getElement(indexValues).getIndex(stateVector); + } + + @Override + public ExpressionNode copy(HashMap variables){ + List copyList = new ArrayList(this.indexVariables.size()); + for(ExpressionNode n : this.indexVariables){ + copyList.add(n.copy(variables)); + } + + return new ArrayElement((ArrayNode) this.array.copy(variables), copyList); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ArrayNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ArrayNode.java new file mode 100644 index 000000000..0a2af8979 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ArrayNode.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ArrayNode extends VarNode{ + private int dimensions = 0; + private List array = null; + private List dimensionList = null; + private List variableList = null; + + public ArrayNode(String name, List array, int dimensions, List dimensionList, List variableList){ + super(name); + this.array = array; + this.dimensions = dimensions; + this.dimensionList = dimensionList; + this.variableList = variableList; + } + + public List getVariableList(){ + return this.variableList; + } + + public int getDimensions(){ + return this.dimensions; + } + + public VarNode getElement(int index){ + if(this.dimensions != 1 || index < 0 || index > (this.dimensionList.get(0) - 1)){ + System.err.println("error: out of bounds array index"); + System.exit(1); + } + + return (VarNode) this.array.get(index); + } + + @SuppressWarnings("unchecked") + public VarNode getElement(List indexList){ + if(this.dimensions != indexList.size()){ + System.err.println("error: incorrect dimensions for array " + this.name); + System.exit(1); + } + + int lastIndex = indexList.size() - 1; + lastIndex = indexList.get(lastIndex).intValue(); + + Object currentArray = this.array; + for(int i = 0; i < indexList.size() - 1; i++){ + int index = indexList.get(i); + if(index < 0 || index > (this.dimensionList.get(i) - 1)){ + System.err.println("error: out of bounds array index"); + System.exit(1); + } + + currentArray = ((List)currentArray).get(index); + } + + if(lastIndex < 0 || lastIndex > (this.dimensionList.get(indexList.size() - 1) - 1)){ + System.err.println("error: out of bounds array index"); + System.exit(1); + } + + return (VarNode) ((List)currentArray).get(lastIndex); + } + + @Override + public void getVariables(HashSet variables){ + variables.add(this); + } + + public List getDimensionList(){ + return this.dimensionList; + } + + @Override + public VarNode clone(){ + return new ArrayNode(this.name, this.array, this.dimensions, this.dimensionList, this.variableList); + } + + @Override + public ExpressionNode copy(HashMap variables){ + VarNode varNode = variables.get(this.name); + if(varNode != null){ + return varNode; + } + int iter = dimensionList.size() - 1; + int dIndex = 0; + int arraySize = dimensionList.get(dIndex++); + int lastSize = 0; + List topLevelArray = new ArrayList(arraySize); + + Queue> arrayQueue = new LinkedList>(); + arrayQueue.offer(topLevelArray); + + while(iter > 0){ + lastSize = arraySize; + arraySize = dimensionList.get(dIndex++); + int qSize = arrayQueue.size(); + for(int i = 0; i < qSize; i++){ + List array = arrayQueue.poll(); + for(int j = 0 ; j < lastSize; j++){ + List newArray = new ArrayList(arraySize); + array.add(j, newArray); + arrayQueue.offer(newArray); + } + } + + iter--; + } + + dIndex--; + arraySize = dimensionList.get(dIndex); + + int nodeIndex = 0; + List varList = new ArrayList(); + while(!arrayQueue.isEmpty()){ + List array = arrayQueue.poll(); + for(int i = 0; i < arraySize; i++){ + VarNode node = this.variableList.get(nodeIndex++); + + VarNode newNode = variables.get(node.getName()); + if(newNode == null){ + newNode = node.clone(); + } + + array.add(i, newNode); + varList.add(newNode); + } + } + + ArrayNode newArray = new ArrayNode(this.name, topLevelArray, this.dimensionList.size(), this.dimensionList, varList); + newArray.setType(this.type); + + return newArray; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitAndNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitAndNode.java new file mode 100644 index 000000000..9cfd8ad06 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitAndNode.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class BitAndNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public BitAndNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + return LeftOperand.evaluate(stateVector) & RightOperand.evaluate(stateVector); + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "&" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new BitAndNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitNegNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitNegNode.java new file mode 100644 index 000000000..a61872719 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitNegNode.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class BitNegNode implements ExpressionNode { + ExpressionNode RightOperand = null; + + public BitNegNode(ExpressionNode rightOperand){ + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + return ~RightOperand.evaluate(stateVector); + } + + @Override + public void getVariables(HashSet variables){ + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return "~" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new BitNegNode(this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitOrNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitOrNode.java new file mode 100644 index 000000000..888d71eed --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitOrNode.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class BitOrNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public BitOrNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + return LeftOperand.evaluate(stateVector) | RightOperand.evaluate(stateVector); + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "|" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new BitOrNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitXorNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitXorNode.java new file mode 100644 index 000000000..2681b4b64 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/BitXorNode.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class BitXorNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public BitXorNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + return LeftOperand.evaluate(stateVector) ^ RightOperand.evaluate(stateVector); + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "^" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new BitXorNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ConstNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ConstNode.java new file mode 100644 index 000000000..a8dcff585 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ConstNode.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ConstNode implements ExpressionNode { + int Value = 0; + String Name; + + public ConstNode(String name, int value){ + this.Name = name; + this.Value = value; + } + + @Override + public int evaluate(int[] stateVector){ + return this.Value; + } + + @Override + public void getVariables(HashSet variables){ + + } + + @Override + public String toString(){ + return "" + Value; + } + + @Override + public ExpressionNode copy(HashMap variables){ + return this; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/DivNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/DivNode.java new file mode 100644 index 000000000..c7bd51990 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/DivNode.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class DivNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public DivNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + return LeftOperand.evaluate(stateVector) / RightOperand.evaluate(stateVector); + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "/" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new DivNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/EquivNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/EquivNode.java new file mode 100644 index 000000000..350c4fb89 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/EquivNode.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class EquivNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public EquivNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + if(LeftOperand.evaluate(stateVector) == RightOperand.evaluate(stateVector)) + return 1; + + return 0; + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "==" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new EquivNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/Expression.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/Expression.java new file mode 100644 index 000000000..16048840d --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/Expression.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Expression { + String ExprString = null; + ExpressionNode ExprNode = null; + HashSet Variables = null; + + public Expression(ExpressionNode expression){ + this.ExprNode = expression; + } + + public Expression(ExpressionNode expression, HashSet variables){ + this.Variables = variables; + this.ExprNode = expression; + } + + public int evaluate(int[] stateVector){ + return ExprNode.evaluate(stateVector); + } + + public HashSet getVariables(){ + if(Variables == null){ + Variables = new HashSet(); + this.ExprNode.getVariables(Variables); + } + + return Variables; + } + + @Override + public String toString(){ + if(ExprString == null){ + ExprString = ExprNode.toString(); + } + + return ExprString; + } + + /** + * Returns a copy of the expression and all subsequent nodes. + * Variable nodes are replaced with the VarNode indexed at it's name + * in the variables HashMap, otherwise a new object is created with + * the same attributes. Constant nodes are not copied. + * @param variables - HashMap of variable nodes keyed with their name + * @return ExpressionNode - New ExpressionNode object + */ + public Expression copy(HashMap variables){ + return new Expression(this.ExprNode.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ExpressionNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ExpressionNode.java new file mode 100644 index 000000000..6217f81ee --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ExpressionNode.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public interface ExpressionNode { + public int evaluate(int[] stateVector); + public void getVariables(HashSet variables); + @Override + public String toString(); + + /** + * Returns a copy of the top level node and all subsequent nodes. + * Variable nodes are replaced with the VarNode indexed at it's name + * in the variables HashMap, otherwise a new object is created with + * the same attributes. Constant nodes are not copied. + * @param variables - HashMap of variable nodes keyed with their name + * @return ExpressionNode - New ExpressionNode object + */ + public ExpressionNode copy(HashMap variables); +} + diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/GreatEqualNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/GreatEqualNode.java new file mode 100644 index 000000000..07d1cbecb --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/GreatEqualNode.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class GreatEqualNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public GreatEqualNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + if(LeftOperand.evaluate(stateVector) >= RightOperand.evaluate(stateVector)) + return 1; + + return 0; + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + ">=" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new GreatEqualNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/GreatNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/GreatNode.java new file mode 100644 index 000000000..3322c5388 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/GreatNode.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class GreatNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public GreatNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + if(LeftOperand.evaluate(stateVector) > RightOperand.evaluate(stateVector)) + return 1; + + return 0; + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + ">" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new GreatNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ImplicationNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ImplicationNode.java new file mode 100644 index 000000000..477a953b3 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ImplicationNode.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ImplicationNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public ImplicationNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + if(LeftOperand.evaluate(stateVector) == 0 || RightOperand.evaluate(stateVector) != 0) + return 1; + + return 0; + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "->" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new ImplicationNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/LeftShiftNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/LeftShiftNode.java new file mode 100644 index 000000000..e7b6abea5 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/LeftShiftNode.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class LeftShiftNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public LeftShiftNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + return LeftOperand.evaluate(stateVector) << RightOperand.evaluate(stateVector); + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "<<" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new LeftShiftNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/LessEqualNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/LessEqualNode.java new file mode 100644 index 000000000..970c65217 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/LessEqualNode.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class LessEqualNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public LessEqualNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + if(LeftOperand.evaluate(stateVector) <= RightOperand.evaluate(stateVector)) + return 1; + + return 0; + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "<=" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new LessEqualNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/LessNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/LessNode.java new file mode 100644 index 000000000..0897dab11 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/LessNode.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class LessNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public LessNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + if(LeftOperand.evaluate(stateVector) < RightOperand.evaluate(stateVector)) + return 1; + + return 0; + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "<" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new LessNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/MinNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/MinNode.java new file mode 100644 index 000000000..1d8c88441 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/MinNode.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class MinNode implements ExpressionNode { + ExpressionNode RightOperand = null; + + public MinNode(ExpressionNode rightOperand){ + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + return -RightOperand.evaluate(stateVector); + } + + @Override + public void getVariables(HashSet variables){ + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return "-" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new MinNode(this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ModNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ModNode.java new file mode 100644 index 000000000..5867ff795 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/ModNode.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ModNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public ModNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + return LeftOperand.evaluate(stateVector) % RightOperand.evaluate(stateVector); + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "%" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new ModNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/MultNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/MultNode.java new file mode 100644 index 000000000..ec8cd595a --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/MultNode.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class MultNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public MultNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + return LeftOperand.evaluate(stateVector) * RightOperand.evaluate(stateVector); + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "*" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new MultNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/NegNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/NegNode.java new file mode 100644 index 000000000..de2065fcc --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/NegNode.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class NegNode implements ExpressionNode { + ExpressionNode RightOperand = null; + + public NegNode(ExpressionNode rightOperand){ + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + if(RightOperand.evaluate(stateVector) == 0) + return 1; + + return 0; + } + + @Override + public void getVariables(HashSet variables){ + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return "!" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new NegNode(this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/NotEquivNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/NotEquivNode.java new file mode 100644 index 000000000..63c1d5c1a --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/NotEquivNode.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class NotEquivNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public NotEquivNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + if(LeftOperand.evaluate(stateVector) != RightOperand.evaluate(stateVector)) + return 1; + + return 0; + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "!=" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new NotEquivNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/OrNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/OrNode.java new file mode 100644 index 000000000..9606750f1 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/OrNode.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class OrNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public OrNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + if(LeftOperand.evaluate(stateVector) != 0 || RightOperand.evaluate(stateVector) != 0) + return 1; + + return 0; + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "||" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new OrNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/RightShiftNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/RightShiftNode.java new file mode 100644 index 000000000..b8b1a9db9 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/RightShiftNode.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class RightShiftNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public RightShiftNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + return LeftOperand.evaluate(stateVector) >> RightOperand.evaluate(stateVector); + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + ">>" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new RightShiftNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/SubNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/SubNode.java new file mode 100644 index 000000000..299c09dcd --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/SubNode.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class SubNode implements ExpressionNode { + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public SubNode(ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + return LeftOperand.evaluate(stateVector) - RightOperand.evaluate(stateVector); + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return LeftOperand.toString() + "-" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new SubNode(this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/TernaryNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/TernaryNode.java new file mode 100644 index 000000000..dc077613a --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/TernaryNode.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class TernaryNode implements ExpressionNode { + ExpressionNode Condition = null; + ExpressionNode LeftOperand = null; + ExpressionNode RightOperand = null; + + public TernaryNode(ExpressionNode condition, ExpressionNode leftOperand, ExpressionNode rightOperand){ + this.Condition = condition; + this.LeftOperand = leftOperand; + this.RightOperand = rightOperand; + } + + @Override + public int evaluate(int[] stateVector){ + if(this.Condition.evaluate(stateVector) != 0) + return LeftOperand.evaluate(stateVector); + + return RightOperand.evaluate(stateVector); + } + + @Override + public void getVariables(HashSet variables){ + LeftOperand.getVariables(variables); + RightOperand.getVariables(variables); + } + + @Override + public String toString(){ + return Condition + "?" + LeftOperand.toString() + ":" + RightOperand.toString(); + } + + @Override + public ExpressionNode copy(HashMap variables){ + return new TernaryNode(this.Condition.copy(variables), this.LeftOperand.copy(variables), this.RightOperand.copy(variables)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/VarNode.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/VarNode.java new file mode 100644 index 000000000..8af4b6c69 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/expression/VarNode.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.expression; + +import java.util.HashMap; +import java.util.HashSet; + +import edu.utah.ece.async.lema.verification.platu.platuLpn.VarType; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class VarNode implements ExpressionNode { + protected String name; // if input, associated output var name + protected String alias = ""; // if input, original var name + protected VarType type = VarType.INTERNAL; + protected int value = 0; + protected int index = -1; + + public VarNode(String name){ + this.name = name; + } + + public VarNode(String name, int index){ + this.name = name; + this.index = index; + } + + public void setName(String name){ + this.name = name; + } + + public void setType(VarType type){ + this.type = type; + } + + public VarType getType(){ + return this.type; + } + + public void setAlias(String alias){ + this.alias = alias; + } + + public String getAlias(){ + return this.alias; + } + + public String getName(){ + return this.name; + } + + public int evaluate(){ + return this.value; + } + + @Override + public int evaluate(int[] stateVector){ + return stateVector[this.index]; + } + + public void setIndex(int index){ + this.index = index; + } + + // TODO: No need to pass in the stateVector for this method. + public int getIndex(int[] stateVector){ + return this.index; + } + + @Override + public void getVariables(HashSet variables){ + variables.add(this); + } + + @Override + public String toString(){ + return name; + } + + @Override + public VarNode clone(){ + VarNode cloneNode = new VarNode(this.name, this.index); + cloneNode.setAlias(this.alias); + cloneNode.setType(this.type); + return cloneNode; + } + + @Override + public ExpressionNode copy(HashMap variables){ + VarNode node = variables.get(this.name); + if(node == null){ + node = this.clone(); + } + + return node; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/Analysis.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/Analysis.java new file mode 100644 index 000000000..018267d17 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/Analysis.java @@ -0,0 +1,5502 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.logicAnalysis; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Observable; +import java.util.PriorityQueue; +import java.util.Stack; + +import edu.utah.ece.async.ibiosim.dataModels.util.GlobalConstants; +import edu.utah.ece.async.ibiosim.dataModels.util.Message; +import edu.utah.ece.async.lema.verification.lpn.Abstraction; +import edu.utah.ece.async.lema.verification.lpn.ExprTree; +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Place; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.lpn.LpnDecomposition.LpnProcess; +import edu.utah.ece.async.lema.verification.platu.MDD.MDT; +import edu.utah.ece.async.lema.verification.platu.MDD.Mdd; +import edu.utah.ece.async.lema.verification.platu.MDD.mddNode; +import edu.utah.ece.async.lema.verification.platu.common.IndexObjMap; +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.markovianAnalysis.ProbGlobalState; +import edu.utah.ece.async.lema.verification.platu.markovianAnalysis.ProbGlobalStateSet; +import edu.utah.ece.async.lema.verification.platu.markovianAnalysis.ProbLocalStateGraph; +import edu.utah.ece.async.lema.verification.platu.partialOrders.DependentSet; +import edu.utah.ece.async.lema.verification.platu.partialOrders.DependentSetComparator; +import edu.utah.ece.async.lema.verification.platu.partialOrders.ProbStaticDependencySets; +import edu.utah.ece.async.lema.verification.platu.partialOrders.StaticDependencySets; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LPNTranRelation; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LpnTranList; +import edu.utah.ece.async.lema.verification.platu.por1.AmpleSet; +import edu.utah.ece.async.lema.verification.platu.project.PrjState; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; +import edu.utah.ece.async.lema.verification.timed_state_exploration.octagon.Equivalence; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zone.TimedStateSet; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.EventSet; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.TimedPrjState; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.Zone; + +import java.util.Queue; +import java.util.Iterator; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Analysis extends Observable{ + + private LinkedList traceCex; + protected Mdd mddMgr = null; + private HashMap> cachedNecessarySets = new HashMap>(); + private final Message message = new Message(); + + /* + * visitedTrans is used in computeNecessary for a disabled transition of interest, to keep track of all transitions visited during trace-back. + */ + private HashSet visitedTrans; + HashMap staticDependency = new HashMap(); + private String separator = GlobalConstants.separator; + + public Analysis(StateGraph[] lpnList, State[] initStateArray, LPNTranRelation lpnTranRelation, String method) { + traceCex = new LinkedList(); + mddMgr = new Mdd(lpnList.length); + + if (method.equals("dfs")) { + //if (Options.getPOR().equals("off")) { + //this.search_dfs(lpnList, initStateArray); + //this.search_dfs_mdd_1(lpnList, initStateArray); + //this.search_dfs_mdd_2(lpnList, initStateArray); + //} + //else + // this.search_dfs_por(lpnList, initStateArray, lpnTranRelation, "state"); + } + else if (method.equals("bfs")==true) + this.search_bfs(lpnList, initStateArray); + else if (method == "dfs_noDisabling") + //this.search_dfs_noDisabling(lpnList, initStateArray); + this.search_dfs_noDisabling_fireOrder(lpnList, initStateArray); + } + + /** + * This constructor performs dfs. + * @param lpnList + */ + public Analysis(StateGraph[] lpnList){ + traceCex = new LinkedList(); + mddMgr = new Mdd(lpnList.length); +// if (method.equals("dfs")) { +// if (Options.getPOR().equals("off")) { +// //this.search_dfs(lpnList, initStateArray); +// this.search_dfsNative(lpnList, initStateArray); +// //this.search_dfs_mdd_1(lpnList, initStateArray); +// //this.search_dfs_mdd_2(lpnList, initStateArray); +// } +// else +// { +// //behavior analysis +// boolean BA = true; +// if(BA==true) +// { +// CompositionalAnalysis.searchCompositional(lpnList); +// this.search_dfs_por(lpnList, initStateArray, lpnTranRelation, "state"); +// } +// else +// this.search_dfs_por(lpnList, initStateArray, lpnTranRelation, "lpn"); +// +// } +// } +// else if (method.equals("bfs")==true) +// this.search_bfs(lpnList, initStateArray); +// else if (method == "dfs_noDisabling") +// //this.search_dfs_noDisabling(lpnList, initStateArray); +// this.search_dfs_noDisabling_fireOrder(lpnList, initStateArray); + } + + /** + * Recursively find all reachable project states. + */ + int iterations = 0; + int stack_depth = 0; + int max_stack_depth = 0; + + public void search_recursive(final StateGraph[] lpnList, + final State[] curPrjState, + final ArrayList> enabledList, + HashSet stateTrace) { + int lpnCnt = lpnList.length; + HashSet prjStateSet = new HashSet(); + + stack_depth++; + if (stack_depth > max_stack_depth) + max_stack_depth = stack_depth; + + iterations++; + if (iterations % 50000 == 0) + System.out.println("iterations: " + iterations + + ", # of prjStates found: " + prjStateSet.size() + + ", max_stack_depth: " + max_stack_depth); + + for (int index = 0; index < lpnCnt; index++) { + LinkedList curEnabledSet = enabledList.get(index); + + if (curEnabledSet == null) + continue; + + for (Transition firedTran : curEnabledSet) { + // while(curEnabledSet.size() != 0) { + // LPNTran firedTran = curEnabledSet.removeFirst(); + + // TODO: (check) Not sure if lpnList[index] is correct + State[] nextStateArray = lpnList[index].fire(lpnList, curPrjState, firedTran); + + // Add nextPrjState into prjStateSet + // If nextPrjState has been traversed before, skip to the next + // enabled transition. + PrjState nextPrjState = new PrjState(nextStateArray); + + //if (stateTrace.contains(nextPrjState) == true) + // System.out.println("found a cycle"); + + if (prjStateSet.add(nextPrjState) == false) { + continue; + } + + // Get the list of enabled transition sets, and call + // findsg_recursive. + ArrayList> nextEnabledList = new ArrayList>(); + for (int i = 0; i < lpnCnt; i++) { + if (curPrjState[i] != nextStateArray[i]) { + StateGraph Lpn_tmp = lpnList[i]; + nextEnabledList.add(i, Lpn_tmp.getEnabled(nextStateArray[i]));// firedTran, + // enabledList.get(i), + // false)); + } else { + nextEnabledList.add(i, enabledList.get(i)); + } + } + + stateTrace.add(nextPrjState); + search_recursive(lpnList, nextStateArray, nextEnabledList, + stateTrace); + stateTrace.remove(nextPrjState); + } + } + } + + + /** + * An iterative implement of findsg_recursive(). + * + * @param sgList + * @param start + * @param curLocalStateArray + * @param enabledArray + */ + public StateSetInterface search_dfs(final StateGraph[] sgList, final State[] initStateArray) { + System.out.println("-------- Reachability Analysis ---------"); + System.out.println("---> calling function search_dfs"); + + double peakUsedMem = 0; + double peakTotalMem = 0; + boolean failure = false; + int tranFiringCnt = 0; + int totalStates = 1; + int numLpns = sgList.length; + Transition firedFailure = null; + + //Stack stateStack = new Stack(); + HashSet stateStack = new HashSet(); + Stack> lpnTranStack = new Stack>(); + Stack curIndexStack = new Stack(); + //HashSet prjStateSet = new HashSet(); + + // Set of PrjStates that have been seen before. Set class documentation + // for how it behaves. Timing Change. +// HashMap prjStateSet = generateStateSet(); + StateSetInterface prjStateSet = generateStateSet(); + + PrjState initPrjState; + // Create the appropriate type for the PrjState depending on whether timing is + // being used or not. Timing Change. + if(!Options.getTimingAnalysisFlag()){ + // If not doing timing. + if (!Options.getMarkovianModelFlag()) + initPrjState = new PrjState(initStateArray); + else + initPrjState = new ProbGlobalState(initStateArray); + } + else{ + // If timing is enabled. + initPrjState = new TimedPrjState(initStateArray); + TimedPrjState.incTSCount(); + + // Set the initial values of the inequality variables. + //((TimedPrjState) initPrjState).updateInequalityVariables(); + } + prjStateSet.add(initPrjState); + if(Options.getMarkovianModelFlag()) { + ((ProbGlobalStateSet) prjStateSet).setInitState(initPrjState); + } + PrjState stateStackTop; + stateStackTop = initPrjState; + if (Options.getDebugMode()) + printStateArray(stateStackTop.toStateArray(), "~~~~ stateStackTop ~~~~"); + stateStack.add(stateStackTop); + constructDstLpnList(sgList); + if (Options.getDebugMode()) + printDstLpnList(sgList); + LpnTranList initEnabled; + if(!Options.getTimingAnalysisFlag()){ // Timing Change. + initEnabled = StateGraph.getEnabledFromTranVector(initStateArray[0]); + } + else + { + // When timing is enabled, it is the project state that will determine + // what is enabled since it contains the zone. This indicates the zeroth zone + // contained in the project and the zeroth LPN to get the transitions from. + initEnabled = ((TimedPrjState) stateStackTop).getPossibleEvents(0, 0); + } + //lpnTranStack.push(initEnabled.clone()); + lpnTranStack.push(initEnabled); + curIndexStack.push(0); + if (Options.getDebugMode()) { + System.out.println("+++++++ Push trans onto lpnTranStack ++++++++"); + printTransList(initEnabled, "initEnabled"); + } + + main_while_loop: while (failure == false && stateStack.size() != 0) { + if (Options.getDebugMode()) { + System.out.println("~~~~~~~~~~~ loop begins ~~~~~~~~~~~"); + } + + long curTotalMem = Runtime.getRuntime().totalMemory(); + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + + if (curTotalMem > peakTotalMem) + peakTotalMem = curTotalMem; + + if (curUsedMem > peakUsedMem) + peakUsedMem = curUsedMem; + + if (stateStack.size() > max_stack_depth) + max_stack_depth = stateStack.size(); + + iterations++; + if (iterations % 100000 == 0) { + System.out.println("---> #iteration " + iterations + + "> # LPN transition firings: " + tranFiringCnt + + ", # of prjStates found: " + totalStates + + ", stack_depth: " + stateStack.size() + + " used memory: " + (float) curUsedMem / 1000000 + + " free memory: " + + (float) Runtime.getRuntime().freeMemory() / 1000000); + } + + State[] curStateArray = stateStackTop.toStateArray(); //stateStack.peek(); + int curIndex = curIndexStack.peek(); + LinkedList curEnabled = lpnTranStack.peek(); + //if (failureTranIsEnabled(curEnabled)) { + firedFailure = failureTranIsEnabled(curEnabled); // Null means no failures. + if(firedFailure != null){ + failure = true; + + if(Options.getTimingAnalysisFlag()&& Options.getOutputSgFlag()){ + // Add the failure transition to the graph. + + TimedPrjState tps = (TimedPrjState) stateStackTop; + + // To have a target state, clone the last state. + TimedPrjState lastState = new TimedPrjState(tps.getStateArray(), tps.get_zones()); + TimedPrjState.incTSCount(); + + stateStackTop.addNextGlobalState(firedFailure, lastState); + } + + break main_while_loop; + } + if (Options.getDebugMode()) { + printStateArray(curStateArray, "------- curStateArray ----------"); + printTransList(curEnabled, "+++++++ curEnabled trans ++++++++"); + } + // If all enabled transitions of the current LPN are considered, + // then consider the next LPN + // by increasing the curIndex. + // Otherwise, if all enabled transitions of all LPNs are considered, + // then pop the stacks. + if (curEnabled.size() == 0) { + lpnTranStack.pop(); + if (Options.getDebugMode()) { + System.out.println("+++++++ Pop trans off lpnTranStack ++++++++"); + printTranStack(lpnTranStack, "***** lpnTranStack *****"); + } + curIndexStack.pop(); + curIndex++; + while (curIndex < numLpns) { +// System.out.println("call getEnabled on curStateArray at 1: "); + if(!Options.getTimingAnalysisFlag()){ // Timing Change + curEnabled = StateGraph.getEnabledFromTranVector(curStateArray[curIndex]).clone(); + } + else{ + // Get the enabled transitions from the zone that are associated with + // the current LPN. + curEnabled = ((TimedPrjState) stateStackTop).getPossibleEvents(0, curIndex); + } + if (curEnabled.size() > 0) { + if (Options.getDebugMode()) { + printTransList(curEnabled, "+++++++ Push trans onto lpnTranStack ++++++++"); + } + lpnTranStack.push(curEnabled); + curIndexStack.push(curIndex); + break; + } + curIndex++; + } + } + if (curIndex == numLpns) { + if (Options.getDebugMode()) { + printStateArray(stateStackTop.toStateArray(), "~~~~ Remove stateStackTop from stateStack ~~~~"); + } + stateStack.remove(stateStackTop); + stateStackTop = stateStackTop.getFather(); + continue; + } + Transition firedTran = curEnabled.removeLast(); + if (Options.getDebugMode()) { + System.out.println("###################"); + System.out.println("Fired transition: " + firedTran.getFullLabel()); + System.out.println("###################"); + } + + State[] nextStateArray; + PrjState nextPrjState; // Moved this definition up. Timing Change. + + // The next state depends on whether timing is in use or not. + // Timing Change. + if(!Options.getTimingAnalysisFlag()){ + nextStateArray = sgList[curIndex].fire(sgList, curStateArray, firedTran); + if (!Options.getMarkovianModelFlag()) + nextPrjState = new PrjState(nextStateArray); + else + nextPrjState = new ProbGlobalState(nextStateArray); + } + else{ + // Get the next timed state and extract the next un-timed states. + nextPrjState = sgList[curIndex].fire(sgList, stateStackTop, + (EventSet) firedTran); + nextStateArray = nextPrjState.toStateArray(); + } + tranFiringCnt++; + + // Check if the firedTran causes disabling error or deadlock. + //LinkedList[] curEnabledArray = new LinkedList[numLpns]; + //LinkedList[] nextEnabledArray = new LinkedList[numLpns]; + //LinkedList[] curEnabledArray = new LinkedList[numLpns]; + //LinkedList[] nextEnabledArray = new LinkedList[numLpns]; + List> curEnabledArray = new ArrayList>(); + List> nextEnabledArray = new ArrayList>(); + for (int i = 0; i < numLpns; i++) { + LinkedList enabledList; + if(!Options.getTimingAnalysisFlag()){ // Timing Change. + enabledList = StateGraph.getEnabledFromTranVector(curStateArray[i]); + } + else{ + // Get the enabled transitions from the Zone for the appropriate + // LPN. + //enabledList = ((TimedPrjState) stateStackTop).getEnabled(i); + enabledList = ((TimedPrjState) stateStackTop).getPossibleEvents(0, i); + } + curEnabledArray.add(i,enabledList); + if(!Options.getTimingAnalysisFlag()){ // Timing Change. + enabledList = StateGraph.getEnabledFromTranVector(nextStateArray[i]); + } + else{ + //enabledList = ((TimedPrjState) nextPrjState).getEnabled(i); + enabledList = ((TimedPrjState) nextPrjState).getPossibleEvents(0, i); + } + nextEnabledArray.add(i,enabledList); + // TODO: (temp) Stochastic model does not need disabling error? + if (Options.getReportDisablingError() && !Options.getMarkovianModelFlag()) { + Transition disabledTran = firedTran.disablingError( + curEnabledArray.get(i), nextEnabledArray.get(i)); + if (disabledTran != null) { + System.err.println("Disabling Error: " + + disabledTran.getFullLabel() + " is disabled by " + + firedTran.getFullLabel()); + failure = true; + break main_while_loop; + } + } + } + + if(!Options.getTimingAnalysisFlag()){ + if (Analysis.deadLock(sgList, nextStateArray) == true) { + System.out.println("*** Verification failed: deadlock."); + failure = true; + break main_while_loop; + } + } + else{ + if (Analysis.deadLock(nextEnabledArray)){ + System.out.println("*** Verification failed: deadlock."); + failure = true; + if(Options.get_displayResults()){ + message.setErrorDialog("Error", "The system deadlocked."); + this.notifyObservers(message); + } + break main_while_loop; + } + } + + // Build transition rate map on global state. + if (Options.getMarkovianModelFlag()) { + for (State localSt : stateStackTop.toStateArray()) { + for (Transition t : localSt.getEnabledTransitions()) { + double tranRate = ((ProbLocalStateGraph) localSt.getLpn().getStateGraph()).getTranRate(localSt, t); + ((ProbGlobalState) stateStackTop).addNextGlobalTranRate(t, tranRate); + } + } + } + + //PrjState nextPrjState = new PrjState(nextStateArray); // Moved earlier. Timing Change. + boolean existingState; + existingState = prjStateSet.contains(nextPrjState); //|| stateStack.contains(nextPrjState); + //existingState = prjStateSet.keySet().contains(nextPrjState); //|| stateStack.contains(nextPrjState); + if (existingState == false) { + prjStateSet.add(nextPrjState); + //prjStateSet.put(nextPrjState,nextPrjState); + stateStackTop.setChild(nextPrjState); + nextPrjState.setFather(stateStackTop); + if (Options.getTimingAnalysisFlag()){ + // Assign a new id. + TimedPrjState tpState = (TimedPrjState) nextPrjState; + tpState.setCurrentId(); + TimedPrjState.incTSCount(); + + if(Options.getOutputSgFlag()){ + // Add the current state as a previous state for the next state. + if(Zone.getSupersetFlag()){ + tpState.addPreviousState((EventSet) firedTran, (TimedPrjState) stateStackTop); + } + } + } + + if (Options.getMarkovianModelFlag() || Options.getOutputSgFlag()) { + stateStackTop.addNextGlobalState(firedTran, nextPrjState); + } +// else { +// if (Options.getDebugMode()) { +// System.out.println("******* curStateArray *******"); +// printStateArray(curStateArray); +// System.out.println("******* nextStateArray *******"); +// printStateArray(nextStateArray); +// System.out.println("stateStackTop: "); +// printStateArray(stateStackTop.toStateArray()); +// System.out.println("firedTran = " + firedTran.getName()); +// System.out.println("***nextStateMap for stateStackTop before firedTran being added: "); +// printNextStateMap(stateStackTop.getNextStateMap()); +// } +// } + stateStackTop = nextPrjState; + stateStack.add(stateStackTop); + lpnTranStack.push((LpnTranList) nextEnabledArray.get(0).clone()); + curIndexStack.push(0); + totalStates++; + if (Options.getDebugMode()) { + printStateArray(stateStackTop.toStateArray(), "~~~~~~~ Add global state to stateStack ~~~~~~~"); + System.out.println("+++++++ Push trans onto lpnTranStack ++++++++"); + printTransList(nextEnabledArray.get(0), ""); + printTranStack(lpnTranStack, "******** lpnTranStack ***********"); + } + } + else { // existingState == true + if (Options.getMarkovianModelFlag()) { + PrjState nextPrjStInStateSet = ((ProbGlobalStateSet) prjStateSet).get(nextPrjState); + stateStackTop.addNextGlobalState(firedTran, nextPrjStInStateSet); + } + else if (!Options.getMarkovianModelFlag() && Options.getOutputSgFlag()) { // non-stochastic model, but need to draw global state graph. + for (PrjState prjSt : prjStateSet) { + if(Options.getTimingAnalysisFlag() && Zone.getSubsetFlag()){ + + TimedPrjState nextTimed = (TimedPrjState) nextPrjState; + + if(nextTimed.subset((TimedPrjState) prjSt)){ + + // If the subset flag is in effect, then a set can be considered + // 'previously seen' if the newly produced state is a subset of + // of the previous set and not just equal. In addition, we cannot + // break, since the current state could be a subset of more than + // one state. + stateStackTop.addNextGlobalState(firedTran, prjSt); + + if(Zone.getSupersetFlag()){ + // If supersets are in effect, add the previous states. + TimedPrjState tps = (TimedPrjState) prjSt; + tps.addPreviousState((EventSet) firedTran, (TimedPrjState) stateStackTop); + } + } + } + else if (prjSt.equals(nextPrjState)) { + stateStackTop.addNextGlobalState(firedTran, prjSt); + break; + } + } + } + else { + if (Options.getOutputSgFlag()) { + if (Options.getDebugMode()) { + printStateArray(curStateArray, "******* curStateArray *******"); + printStateArray(nextStateArray, "******* nextStateArray *******"); + printStateArray(stateStackTop.toStateArray(), "stateStackTop: "); + System.out.println("firedTran = " + firedTran.getFullLabel()); +// System.out.println("nextStateMap for stateStackTop before firedTran being added: "); +// printNextGlobalStateMap(stateStackTop.getNextStateMap()); + } + } + } + } + } + double totalStateCnt =0; + totalStateCnt = prjStateSet.size(); + System.out.println("---> final numbers: # LPN transition firings: " + tranFiringCnt + + ", # of prjStates found: " + totalStateCnt + + ", max_stack_depth: " + max_stack_depth + + ", peak total memory: " + peakTotalMem / 1000000 + " MB" + + ", peak used memory: " + peakUsedMem / 1000000 + " MB"); + if(Options.getTimingAnalysisFlag()){// && !failure){ + if(!failure){ + if(Options.get_displayResults()){ + message.setErrorDialog("Success", "Verification was successful."); + this.notifyObservers(message); + } + System.out.println("Verification was successful"); + } + else{ + System.out.println("************ System failed. ***********"); + if(firedFailure != null){ + if(Options.get_displayResults()){ + + message.setErrorDialog("Error", "Failure transition " + firedFailure.getLabel() + " is enabled."); + this.notifyObservers(message); + } + System.out.println("The failure transition" + firedFailure.getLabel() + "fired."); + } + else{ + if(Options.get_displayResults()){ + + message.setErrorDialog("Error", "System failed for reason other\nthan a failure transition."); + this.notifyObservers(message); + } + } + } + System.out.println(prjStateSet.toString()); + + + } + if (Options.getOutputLogFlag()) + writePerformanceResultsToLogFile(false, tranFiringCnt, totalStateCnt, peakTotalMem / 1000000, peakUsedMem / 1000000); + if (Options.getOutputSgFlag()) { + System.out.println("outputSGPath = " + Options.getPrjSgPath()); + + //drawGlobalStateGraph(sgList, prjStateSet.toHashSet(), true); + //drawReducedStateGraph(initPrjState); + drawGlobalStateGraph(initPrjState, prjStateSet); + } +// // ---- TEMP ---- +// try{ +// File stateFile = new File(Options.getPrjSgPath() + Options.getLogName() + ".txt"); +// FileWriter fileWritter = new FileWriter(stateFile,true); +// BufferedWriter bufferWritter = new BufferedWriter(fileWritter); +// // TODO: Need to merge variable vectors from different local states. +// ArrayList vector; +// String curPrjStInfo = ""; +// for (PrjState prjSt : prjStateSet) { +// curPrjStInfo += "--- Begin ---\n"; +// // marking +// curPrjStInfo += "marking: "; +// for (State localSt : prjSt.toStateArray()) +// curPrjStInfo += intArrayToString("markings", localSt) + "\n"; +// // variable vector +// curPrjStInfo += "var values: "; +// for (State localSt : prjSt.toStateArray()) { +// localSt.getLpn().getAllVarsWithValuesAsInt(localSt.getVariableVector()); +// //curPrjStInfo += intArrayToString("vars", localSt)+ "\n"; +// } +// +// // tranVector +// curPrjStInfo += "tran vector: "; +// for (State localSt : prjSt.toStateArray()) +// curPrjStInfo += boolArrayToString("enabled trans", localSt)+ "\n"; +// curPrjStInfo += "--- End ---\n"; +// bufferWritter.write(curPrjStInfo); +// //bufferWritter.flush(); +// } +// bufferWritter.close(); +// System.out.println("Done writing state file."); +// }catch(IOException e){ +// e.printStackTrace(); +// } +// //--------------- + return prjStateSet; + } + +// private boolean failureCheck(LinkedList curEnabled) { +// boolean failureTranIsEnabled = false; +// for (Transition tran : curEnabled) { +// if (tran.isFail()) { +// JOptionPane.showMessageDialog(Gui.frame, +// "Failure transition " + tran.getLabel() + " is enabled.", "Error", +// JOptionPane.ERROR_MESSAGE); +// failureTranIsEnabled = true; +// break; +// } +// } +// return failureTranIsEnabled; +// } + +// /** +// * Generates the appropriate version of a HashSet for storing +// * the "already seen" set of project states. +// * @return +// * Returns a HashSet, a StateSet, or a ProbGlobalStateSet +// * depending on the type. +// */ +// private HashSet generateStateSet(){ +// +// boolean timed = Options.getTimingAnalysisFlag(); +// boolean subsets = Zone.getSubsetFlag(); +// boolean supersets = Zone.getSupersetFlag(); +// +// if(Options.getMarkovianModelFlag()){ +// return new ProbGlobalStateSet(); +// } +// else if(timed && (subsets || supersets)){ +// return new TimedStateSet(); +// } +// +// return new HashSet(); +// } + + /** + * Generates the appropriate version of a HashSet for storing + * the "already seen" set of project states. + * @return + * Returns a HashSet, a StateSet, or a ProbGlobalStateSet + * depending on the type. + */ + private static StateSetInterface generateStateSet(){ + + boolean timed = Options.getTimingAnalysisFlag(); + boolean subsets = Zone.getSubsetFlag(); + boolean supersets = Zone.getSupersetFlag(); + + if(Options.getMarkovianModelFlag()){ + return new ProbGlobalStateSet(); + } + else if(timed && (subsets || supersets)){ + return new TimedStateSet(); + } + + return new HashSetWrapper(); + } + + private static Transition failureTranIsEnabled(LinkedList enabledTrans) { + Transition failure = null; + for (Transition tran : enabledTrans) { + if (tran.isFail()) { + + if(Zone.get_writeLogFile() != null){ + try { + Zone.get_writeLogFile().write(tran.getLabel()); + Zone.get_writeLogFile().newLine(); + } catch (IOException e) { + e.printStackTrace(); + } + } +// +// JOptionPane.showMessageDialog(Gui.frame, +// "Failure transition " + tran.getLabel() + " is enabled.", "Error", +// JOptionPane.ERROR_MESSAGE); + return tran; + } + } + return failure; + } + + public static class ReducedStateGraph { + + private PrjState initState; + private HashSet stateSet; // list of all states of given state graph + private HashMap > statePreSet; // input transitions for each state + private HashMap > statePostSet; // output transitions for each state + private HashMap > stateVars; // list of care variables for each state + private HashSet careVars; // list of care variables + + ReducedStateGraph (PrjState initGlobalState) { + try { + // Initialize class variables + stateSet = new HashSet(); + statePreSet = new HashMap>(); + statePostSet = new HashMap>(); + stateVars = new HashMap>(); + careVars = new HashSet(); + + // Values for c-element example + //careVars.add("A"); + //careVars.add("B"); + //careVars.add("C"); + + careVars.add("gp"); + careVars.add("gn"); + careVars.add("gp_ack"); + careVars.add("gn_ack"); + careVars.add("oc"); + careVars.add("uv"); + + + HashSet reducedStateSet = new HashSet(); // list of care states + + // Add initial state + stateSet.add(initGlobalState); + reducedStateSet.add(initGlobalState); + initState = initGlobalState; + statePreSet.put(initGlobalState, new HashSet ()); + statePostSet.put(initGlobalState, new HashSet ()); + + HashSet visited = new HashSet (); + visited.add(initGlobalState); + + Queue stateQueue = new LinkedList (); + stateQueue.add(initGlobalState); + + // Traverse graph via bfs and mark noncare states + while (!stateQueue.isEmpty()) { + PrjState curState = stateQueue.remove(); + HashMap curStateVars = getCareVars(curState); + stateVars.put(curState, curStateVars); + + for (Transition outTran : curState.getNextGlobalStateMap().keySet()) { + PrjState nextState = curState.getNextGlobalStateMap().get(outTran); + HashMap nextStateVars = getCareVars(nextState); + stateVars.put(nextState, nextStateVars); + + if (!visited.contains(nextState)) { + visited.add(nextState); + stateQueue.add(nextState); + statePreSet.put(nextState, new HashSet ()); + statePostSet.put(nextState, new HashSet ()); + } + + // Check if care variables in the next state are equal to those in the current state + if (!stateVars.get(curState).equals(stateVars.get(nextState))) + reducedStateSet.add(nextState); + + statePreSet.get(nextState).add(curState); + statePostSet.get(curState).add(nextState); + stateSet.add(nextState); + + } + } + + + Iterator nextStateIter = stateSet.iterator(); + + // Remove unmarked states and update transitions + while(nextStateIter.hasNext()) { + PrjState nextState = nextStateIter.next(); + + if (!reducedStateSet.contains(nextState)) { + //stateSet.remove(nextState); + + // Update preset states + Iterator preSetStateIter = statePreSet.get(nextState).iterator(); + while(preSetStateIter.hasNext()) { + PrjState preSetState = preSetStateIter.next(); + statePostSet.get(preSetState).addAll(statePostSet.get(nextState)); + } + + // Update post states + Iterator postSetStateIter = statePostSet.get(nextState).iterator(); + while(postSetStateIter.hasNext()) { + PrjState postSetState = postSetStateIter.next(); + statePreSet.get(postSetState).addAll(statePreSet.get(nextState)); + } + + } + } + + stateSet = reducedStateSet; + + HashMap> statePreSetTemp = new HashMap>(); + HashMap> statePostSetTemp = new HashMap>(); + + // Remove transitions to unmarked states + nextStateIter = stateSet.iterator(); + while(nextStateIter.hasNext()) { + PrjState nextState = nextStateIter.next(); + statePreSetTemp.put(nextState, new HashSet()); + statePostSetTemp.put(nextState, new HashSet()); + + // Update preset states + Iterator preSetStateIter = statePreSet.get(nextState).iterator(); + while(preSetStateIter.hasNext()) { + PrjState preSetState = preSetStateIter.next(); + if (stateSet.contains(preSetState)) + statePreSetTemp.get(nextState).add(preSetState); + } + + // Update post states + Iterator postSetStateIter = statePostSet.get(nextState).iterator(); + while(postSetStateIter.hasNext()) { + PrjState postSetState = postSetStateIter.next(); + if (stateSet.contains(postSetState)) + statePostSetTemp.get(nextState).add(postSetState); + } + } + + statePostSet = statePostSetTemp; + statePreSet = statePreSetTemp; + + } catch (Exception e) { + e.printStackTrace(); + System.err.println("Error creating reduced state graph."); + } + + } + + private void mergeDublicates() { + try { + boolean reductionFound = true; + + while (reductionFound) { + reductionFound = false; + + Iterator curStateIter = stateSet.iterator(); + PrjState preSetState1 = new PrjState(); + PrjState preSetState2 = new PrjState(); + + // Iterate over all states to identify states with same coding in the preset + while(curStateIter.hasNext() && !reductionFound) { + PrjState nextState = curStateIter.next(); + + // TODO: use hash to identify same vector values + Iterator preSetStateIter1 = statePreSet.get(nextState).iterator(); + while(preSetStateIter1.hasNext() && !reductionFound) { + preSetState1 = preSetStateIter1.next(); + + Iterator preSetStateIter2 = statePreSet.get(nextState).iterator(); + while(preSetStateIter2.hasNext() && !reductionFound) { + preSetState2 = preSetStateIter2.next(); + + // TODO: think on checking similar postsets for states with similar encoding + // It is possible there different paths in the graph + if (stateVars.get(preSetState1).equals(stateVars.get(preSetState2)) && !preSetState1.equals(initState) && !preSetState2.equals(initState) + && !preSetState1.equals(preSetState2)) + reductionFound = true; + + } + } + } + + // If reduction found merge two states and start over + if (reductionFound) + mergeStates(preSetState1, preSetState2); + + } + + // Remove self loops + Iterator curStateIter = stateSet.iterator(); + + // Iterate over all states to identify states with same coding in the preset + while(curStateIter.hasNext()) { + PrjState nextState = curStateIter.next(); + + statePreSet.get(nextState).remove(nextState); + statePostSet.get(nextState).remove(nextState); + } + + } catch (Exception e) { + e.printStackTrace(); + System.err.println("Error removing dublicates from reduced state graph."); + } + } + + private void mergeStates(PrjState stateA, PrjState stateB) { + try { + + // Copy preset states + HashSet statePreSetLocal = statePreSet.get(stateB); + statePreSetLocal.addAll(statePreSet.get(stateA)); + statePreSet.put(stateA, statePreSetLocal); + + // Update postset of all connected states + Iterator preSetStateIter = statePreSet.get(stateA).iterator(); + while(preSetStateIter.hasNext()) { + PrjState preSetState = preSetStateIter.next(); + // To avoid selfloops + if (!preSetState.equals(stateA)) + statePostSet.get(preSetState).add(stateA); + statePostSet.get(preSetState).remove(stateB); + } + + // Copy post states + HashSet statePostSetLocal = statePostSet.get(stateB); + statePostSetLocal.addAll(statePostSet.get(stateA)); + statePostSet.put(stateA, statePostSetLocal); + + // Update pretset of all connected states + Iterator postSetStateIter = statePostSet.get(stateA).iterator(); + while(postSetStateIter.hasNext()) { + PrjState postSetState = postSetStateIter.next(); + // To avoid selfloops + if (!postSetState.equals(stateA)) + statePreSet.get(postSetState).add(stateA); + statePreSet.get(postSetState).remove(stateB); + } + + stateSet.remove(stateB); + statePreSet.remove(stateB); + statePostSet.remove(stateB); + + } catch (Exception e) { + e.printStackTrace(); + System.err.println("Error merging states in reduced state graph."); + } + + } + + private HashMap getCareVars(PrjState globalState) { + HashMap vars = new HashMap(); + for (State curLocalState : globalState.toStateArray()) { + LPN curLpn = curLocalState.getLpn(); + for(int i = 0; i < curLpn.getVarIndexMap().size(); i++) { + if (careVars.contains(curLpn.getVarIndexMap().getKey(i))) + vars.put(curLpn.getVarIndexMap().getKey(i), curLocalState.getVariableVector()[i]); + } + } + + return vars; + } + + private String getLabel(PrjState stateA, PrjState stateB) { + String label = null; + + try { + HashMap stateAVars = stateVars.get(stateA); + HashMap stateBVars = stateVars.get(stateB); + + Iterator curVarIter = careVars.iterator(); + while (curVarIter.hasNext()) { + String varName = curVarIter.next(); + + if (stateAVars.get(varName) > stateBVars.get(varName)) { + if (label == null) + label = varName + "-"; + else { + label = "Error"; + break; + } + } + + if (stateAVars.get(varName) < stateBVars.get(varName)) { + if (label == null) + label = varName + "+"; + else { + label = "Error"; + break; + } + } + } + + } catch (Exception e) { + e.printStackTrace(); + System.err.println("Error getting arc label in reduced state graph."); + } + return label; + } + + public void drawPetrifySG(String fileName) { + try { + String fileNameLocal = null; + fileNameLocal = Options.getPrjSgPath() + fileName; + + BufferedWriter out = new BufferedWriter(new FileWriter(fileNameLocal)); + out.write("# Reduced state graph, generated by LEMA\n"); + out.write(".inputs" + careVars.toString() + "\n"); + out.write(".state graph\n"); + + for (PrjState curState : statePostSet.keySet()) { + Iterator nextStateIter = statePostSet.get(curState).iterator(); + while(nextStateIter.hasNext()) { + PrjState nextState = nextStateIter.next(); + String arcLabel = getLabel(curState, nextState); + out.write("TS_" + ((TimedPrjState) curState).getTSID() + " " + arcLabel + " " + "TS_" + ((TimedPrjState) nextState).getTSID() + "\n"); + } + } + + + out.write(".marking {" + "TS_" + ((TimedPrjState) initState).getTSID() + "}\n"); + out.write(".end"); + out.close(); + + } catch (Exception e) { + e.printStackTrace(); + System.err.println("Error producing petrify state graph file."); + } + } + + public void drawGraph(String fileName) { + try { + String fileNameLocal = null; + fileNameLocal = Options.getPrjSgPath() + fileName; + + BufferedWriter out = new BufferedWriter(new FileWriter(fileNameLocal)); + out.write("digraph G {\n"); + out.write("node [shape=box, style=rounded]" + "\n"); + + Iterator curStateIter = stateSet.iterator(); + while(curStateIter.hasNext()) { + PrjState curState = curStateIter.next(); + if (curState.equals(initState)) + out.write("TS_" + ((TimedPrjState) curState).getTSID() + "[label=\"" + "TS_" + ((TimedPrjState) curState).getTSID() + + "\\n" + stateVars.get(curState) + "\", style=\"rounded, filled\"]" + "\n"); + else + out.write("TS_" + ((TimedPrjState) curState).getTSID() + "[label=\"" + "TS_" + ((TimedPrjState) curState).getTSID() + + "\\n" + stateVars.get(curState) + "\"]" + "\n"); + + Iterator nextStateIter = statePostSet.get(curState).iterator(); + while(nextStateIter.hasNext()) { + PrjState nextState = nextStateIter.next(); + String arcLabel = getLabel(curState, nextState); + out.write("TS_" + ((TimedPrjState) curState).getTSID() + "->" + "TS_" + ((TimedPrjState) nextState).getTSID() + + "[label=\""+ arcLabel + "\"]" +"\n"); + } + + } + + out.write("}"); + out.close(); + + } catch (Exception e) { + e.printStackTrace(); + System.err.println("Error producing reduced state graph as dot file."); + } + } + } + + public static void drawReducedStateGraph(PrjState initGlobalState) { + ReducedStateGraph reducedStateGraph = new ReducedStateGraph (initGlobalState); + reducedStateGraph.drawGraph("Reduced.dot"); + reducedStateGraph.drawPetrifySG("Reduced.sg"); + reducedStateGraph.mergeDublicates(); + reducedStateGraph.drawGraph("Reduced_merged.dot"); + reducedStateGraph.drawPetrifySG("Reduced_merged.sg"); + } + + + /** + * Produces DOT files for visualizing the global state graph.

+ * This method assumes that the global state graph exists. + * @param initGlobalState + * @param globalStateSet + */ + public static void drawGlobalStateGraph(PrjState initGlobalState, StateSetInterface globalStateSet) { + try { + String fileName = null; + if (Options.getPOR().toLowerCase().equals("off")) { + fileName = Options.getPrjSgPath() + "full_sg.dot"; + } + else { + fileName = Options.getPrjSgPath() + Options.getPOR().toLowerCase() + "_" + + Options.getCycleClosingMthd().toLowerCase() + "_" + + Options.getCycleClosingStrongStubbornMethd().toLowerCase() + "_sg.dot"; + } + BufferedWriter out = new BufferedWriter(new FileWriter(fileName)); + NumberFormat num = NumberFormat.getNumberInstance();//NumberFormat.getInstance(); + num.setMaximumFractionDigits(6); + num.setGroupingUsed(false); + out.write("digraph G {\n"); + out.write("node [shape=box, style=rounded]"); + for (PrjState curGlobalState : globalStateSet) { + // Build composite current global state. + String curVarNames = ""; + String curVarValues = ""; + String curMarkings = ""; + String curEnabledTrans = ""; + String curGlobalStateLabel = ""; + String curGlobalStateProb = null; + String DBM = ""; + HashMap vars = new HashMap(); + for (State curLocalState : curGlobalState.toStateArray()) { + curGlobalStateLabel = curGlobalStateLabel + "_" + "S" + curLocalState.getIndex(); + LPN curLpn = curLocalState.getLpn(); + for(int i = 0; i < curLpn.getVarIndexMap().size(); i++) { + vars.put(curLpn.getVarIndexMap().getKey(i), curLocalState.getVariableVector()[i]); + } + curMarkings = curMarkings + "," + intArrayToString("markings", curLocalState); + if (!boolArrayToString("enabled trans", curLocalState).equals("")) + curEnabledTrans = curEnabledTrans + "," + boolArrayToString("enabled trans", curLocalState); + } + for (String vName : vars.keySet()) { + Integer vValue = vars.get(vName); + curVarValues = curVarValues + vValue + ", "; + curVarNames = curVarNames + vName + ", "; + } + if (!curVarNames.isEmpty() && !curVarValues.isEmpty()) { + curVarNames = curVarNames.substring(0, curVarNames.lastIndexOf(",")); + curVarValues = curVarValues.substring(0, curVarValues.lastIndexOf(",")); + } + curMarkings = curMarkings.substring(curMarkings.indexOf(",")+1, curMarkings.length()); + curEnabledTrans = curEnabledTrans.substring(curEnabledTrans.indexOf(",")+1, curEnabledTrans.length()); + if (Options.getMarkovianModelFlag()) { + // State probability after steady state analysis. + curGlobalStateProb = num.format(((ProbGlobalState) curGlobalState).getCurrentProb()); + } + if(Options.getTimingAnalysisFlag()){ + TimedPrjState timedState = (TimedPrjState) curGlobalState; + + curGlobalStateLabel = "TS_" + timedState.getTSID(); + + if(Options.get_displayDBM()){ + + Equivalence[] dbm = timedState.get_zones(); + + DBM = "\\n" + dbm[0].toString().replace("\n", "\\n") + "\\n"; + } + } + else{ + curGlobalStateLabel = curGlobalStateLabel.substring(curGlobalStateLabel.indexOf("_")+1, curGlobalStateLabel.length()); + } + + if (curGlobalState.equals(initGlobalState)) { + String sgVector = ""; // sgVector is a vector of LPN labels. It shows the order of local state graph composition. + for (State s : initGlobalState.toStateArray()) { + sgVector = sgVector + s.getLpn().getLabel() + ", "; + } + out.write("Inits[shape=plaintext, label=\"variable vector:<" + curVarNames + ">\\n" + "LPN vector:<" +sgVector.substring(0, sgVector.lastIndexOf(",")) + ">\"]\n"); + if (!Options.getMarkovianModelFlag()) { + out.write(curGlobalStateLabel + "[label=\"" + curGlobalStateLabel + "\\n<"+curVarValues+">" + + "\\n<"+curEnabledTrans+">" + "\\n<"+curMarkings+">" + "\\n" + DBM + "\\n" + "\", style=\"rounded, filled\"]\n"); + } + else { + out.write(curGlobalStateLabel + "[label=\"" + curGlobalStateLabel + "\\n<"+curVarValues+">" + + "\\n<"+curEnabledTrans+">" + "\\n<"+curMarkings+">" + "\\nProb = " + curGlobalStateProb + "\", style=\"rounded, filled\"]\n"); + } + } + else { // non-initial global state(s) + if (!Options.getMarkovianModelFlag()) { + out.write(curGlobalStateLabel + "[label=\"" + curGlobalStateLabel + "\\n<"+curVarValues+">" + + "\\n<"+curEnabledTrans+">" + "\\n<"+curMarkings+">" + "\\n" + DBM + "\\n" + "\"]\n"); + } + else { + out.write(curGlobalStateLabel + "[label=\"" + curGlobalStateLabel + "\\n<"+curVarValues+">" + + "\\n<"+curEnabledTrans+">" + "\\n<"+curMarkings+">" + "\\nProb = " + curGlobalStateProb + "\"]\n"); + } + } + for (Transition outTran : curGlobalState.getNextGlobalStateMap().keySet()) { + PrjState nextGlobalState = curGlobalState.getNextGlobalStateMap().get(outTran); + String nextGlobalStateLabel = ""; + if(Options.getTimingAnalysisFlag()){ + nextGlobalStateLabel = "TS_" + ((TimedPrjState)nextGlobalState).getTSID(); + }else{ + nextGlobalStateLabel = nextGlobalState.getLabel(); + } + String outTranName = outTran.getLabel(); + if (!Options.getMarkovianModelFlag()) { + if (outTran.isFail() && !outTran.isPersistent()) + out.write(curGlobalStateLabel + "->" + nextGlobalStateLabel + "[label=\"" + outTranName + "\", fontcolor=red]\n"); + else if (!outTran.isFail() && outTran.isPersistent()) { +// out.write(curGlobalStateLabel + "[label=\"" + curGlobalStateLabel + "\\n<"+curVarValues+">" +// + "\\n<"+curEnabledTrans+">" + "\\n<"+curMarkings+">" + "\"]\n"); + out.write(curGlobalStateLabel + "->" + nextGlobalStateLabel + "[label=\"" + outTranName + "\", fontcolor=blue]\n"); + } + else if (outTran.isFail() && outTran.isPersistent()) + out.write(curGlobalStateLabel + "->" + nextGlobalStateLabel + "[label=\"" + outTranName + "\", fontcolor=purple]\n"); + else { +// out.write(curGlobalStateLabel + "[label=\"" + curGlobalStateLabel + "\\n<"+curVarValues+">" +// + "\\n<"+curEnabledTrans+">" + "\\n<"+curMarkings+">" + "\"]\n"); + out.write(curGlobalStateLabel + "->" + nextGlobalStateLabel + "[label=\"" + outTranName + "\"]\n"); + } + } + else { // stochastic global state graph + //State localState = curGlobalState.toStateArray()[outTran.getLpn().getLpnIndex()]; + //String outTranRate = num.format(((ProbLocalStateGraph) localState.getStateGraph()).getTranRate(localState, outTran)); + String outTranRate = num.format(((ProbGlobalState) curGlobalState).getOutgoingTranRate(outTran)); + + if (outTran.isFail() && !outTran.isPersistent()) + out.write(curGlobalStateLabel + "->" + nextGlobalStateLabel + + "[label=\"" + outTranName + "\\n" + outTranRate + "\", fontcolor=red]\n"); + else if (!outTran.isFail() && outTran.isPersistent()) + out.write(curGlobalStateLabel + "->" + nextGlobalStateLabel + + "[label=\"" + outTranName + "\\n" + outTranRate + "\", fontcolor=blue]\n"); + else if (outTran.isFail() && outTran.isPersistent()) + out.write(curGlobalStateLabel + "->" + nextGlobalStateLabel + + "[label=\"" + outTranName + "\\n" + outTranRate + "\", fontcolor=purple]\n"); + else + out.write(curGlobalStateLabel + "->" + nextGlobalStateLabel + + "[label=\"" + outTranName + "\\n" + outTranRate + "\"]\n"); + } + } + } + out.write("}"); + out.close(); + } + catch (Exception e) { + e.printStackTrace(); + System.err.println("Error producing global state graph as dot file."); + } + } + + private void drawDependencyGraphs(LPN[] lpnList) { + String fileName = Options.getPrjSgPath() + separator + "dependencyGraph.dot"; + BufferedWriter out; + try { + out = new BufferedWriter(new FileWriter(fileName)); + out.write("digraph G {\n"); + for (Transition curTran : staticDependency.keySet()) { + String curTranStr = curTran.getLpn().getLabel() + "_" + curTran.getLabel(); + out.write(curTranStr + "[shape=\"box\"];"); + out.newLine(); + } + for (Transition curTran : staticDependency.keySet()) { + StaticDependencySets curStaticSets = staticDependency.get(curTran); + String curTranStr = curTran.getLpn().getLabel() + "_" + curTran.getLabel(); + // TODO: getOtherTransDisableCurTranSet(false) or getOtherTransDisableCurTranSet(true) + for (Transition curTranInDisable : curStaticSets.getOtherTransDisableSeedTran(false)) { + String curTranInDisableStr = curTranInDisable.getLpn().getLabel() + "_" + curTranInDisable.getLabel(); + out.write(curTranInDisableStr + "->" + curTranStr + "[color=\"chocolate\"];"); + out.newLine(); + } +// for (Transition curTranInDisable : curStaticSets.getCurTranDisableOtherTransSet()) { +// String curTranInDisableStr = lpnList[curTranInDisable.getLpnIndex()].getLabel() +// + "_" + lpnList[curTranInDisable.getLpnIndex()].getTransition(curTranInDisable.getTranIndex()).getName(); +// out.write(curTranStr + "->" + curTranInDisableStr + "[color=\"chocolate\"];"); +// out.newLine(); +// } +// for (Transition curTranInDisable : curStaticSets.getDisableSet()) { +// String curTranInDisableStr = lpnList[curTranInDisable.getLpnIndex()].getLabel() +// + "_" + lpnList[curTranInDisable.getLpnIndex()].getTransition(curTranInDisable.getTranIndex()).getName(); +// out.write(curTranStr + "->" + curTranInDisableStr + "[color=\"blue\"];"); +// out.newLine(); +// } + HashSet enableByBringingToken = new HashSet(); + for (Place p : curTran.getPreset()) { + for (Transition presetTran : p.getPreset()) { + enableByBringingToken.add(presetTran); + } + } + for (Transition curTranInCanEnable : enableByBringingToken) { + String curTranInCanEnableStr = curTranInCanEnable.getLpn().getLabel() + "_" + curTranInCanEnable.getLabel(); + out.write(curTranStr + "->" + curTranInCanEnableStr + "[color=\"mediumaquamarine\"];"); + out.newLine(); + } + + for (HashSet canEnableOneConjunctSet : curStaticSets.getOtherTransSetSeedTranEnablingTrue()) { + for (Transition curTranInCanEnable : canEnableOneConjunctSet) { + String curTranInCanEnableStr = curTranInCanEnable.getLpn().getLabel() + "_" + curTranInCanEnable.getLabel(); + out.write(curTranStr + "->" + curTranInCanEnableStr + "[color=\"deepskyblue\"];"); + out.newLine(); + } + } + } + out.write("}"); + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + private static String intArrayToString(String type, State curState) { + String arrayStr = ""; + if (type.equals("markings")) { + for (int i=0; i< curState.getMarking().length; i++) { + if (curState.getMarking()[i] == 1) { + arrayStr = arrayStr + curState.getLpn().getPlaceList()[i] + ","; + } +// String tranName = curState.getLpn().getAllTransitions()[i].getName(); +// if (curState.getTranVector()[i]) +// System.out.println(tranName + " " + "Enabled"); +// else +// System.out.println(tranName + " " + "Not Enabled"); + } + if (arrayStr.contains(",")) + arrayStr = arrayStr.substring(0, arrayStr.lastIndexOf(",")); + } + else if (type.equals("vars")) { + for (int i=0; i< curState.getVariableVector().length; i++) { + arrayStr = arrayStr + curState.getVariableVector()[i] + ","; + } + if (arrayStr.contains(",")) + arrayStr = arrayStr.substring(0, arrayStr.lastIndexOf(",")); + } + return arrayStr; + } + + private static String boolArrayToString(String type, State curState) { + String arrayStr = ""; + if (type.equals("enabled trans")) { + for (int i=0; i< curState.getTranVector().length; i++) { + if (curState.getTranVector()[i]) { + //arrayStr = arrayStr + curState.getLpn().getAllTransitions()[i].getFullLabel() + ", "; + arrayStr = arrayStr + curState.getLpn().getAllTransitions()[i].getLabel() + ", "; + } + } + if (arrayStr != "") + arrayStr = arrayStr.substring(0, arrayStr.lastIndexOf(",")); + } + return arrayStr; + } + + private static void printStateArray(State[] stateArray, String title) { + if (title != null) + System.out.println(title); + for (int i=0; i tranList, String title) { + if (title != null && !title.equals("")) + System.out.println("+++++++" + title + "+++++++"); + for (int i=0; i< tranList.size(); i++) + System.out.println(tranList.get(i).getFullLabel() + ", "); + System.out.println("+++++++++++++"); + } + +// private void writeIntegerStackToDebugFile(Stack curIndexStack, String title) { +// if (title != null) +// System.out.println(title); +// for (int i=0; i < curIndexStack.size(); i++) { +// System.out.println(title + "[" + i + "]" + curIndexStack.get(i)); +// } +// System.out.println("------------------"); +// } + + private static void printDstLpnList(StateGraph[] lpnList) { + System.out.println("++++++ dstLpnList ++++++"); + for (int i=0; i calling function searchPOR_traceback"); + System.out.println("---> " + Options.getPOR()); + System.out.println("---> " + Options.getCycleClosingMthd()); + System.out.println("---> " + Options.getCycleClosingStrongStubbornMethd()); + + double peakUsedMem = 0; + double peakTotalMem = 0; + boolean failure = false; + int tranFiringCnt = 0; + int totalStates = 1; + int numLpns = sgList.length; + Transition firedFailure = null; + + LPN[] lpnList = new LPN[numLpns]; + for (int i=0; i stateStack = new HashSet(); + Stack> lpnTranStack = new Stack>(); + StateSetInterface prjStateSet = generateStateSet(); + PrjState initPrjState; + // Create the appropriate type for the PrjState depending on whether timing is + // being used or not. + if (!Options.getMarkovianModelFlag()) { + initPrjState = new PrjState(initStateArray); + } + else { + initPrjState = new ProbGlobalState(initStateArray); + } + prjStateSet.add(initPrjState); + if(Options.getMarkovianModelFlag()) { + ((ProbGlobalStateSet) prjStateSet).setInitState(initPrjState); + } + PrjState stateStackTop = initPrjState; + if (Options.getDebugMode()) + printStateArray(stateStackTop.toStateArray(), "%%%%%%% stateStackTop %%%%%%%%"); + stateStack.add(stateStackTop); + constructDstLpnList(sgList); + if (Options.getDebugMode()) + printDstLpnList(sgList); + // Determine statistically the dependency relations between transitions. + HashMap allTransitions = new HashMap(lpnList.length); + //HashMap staticSetsMap = new HashMap(); + HashMap allProcessTransInOneLpn = new HashMap(); + HashMap allTransitionsToLpnProcesses = new HashMap(); + for (int lpnIndex=0; lpnIndex processMapForOneLpn = new HashMap(); + for (Transition curTran: allProcessTransInOneLpn.keySet()) { + Integer procId = allProcessTransInOneLpn.get(curTran); + if (!processMapForOneLpn.containsKey(procId)) { + LpnProcess newProcess = new LpnProcess(procId); + newProcess.addTranToProcess(curTran); + if (curTran.getPreset() != null) { + if (newProcess.getStateMachineFlag() + && ((curTran.getPreset().length > 1) + || (curTran.getPostset().length > 1))) { + newProcess.setStateMachineFlag(false); + } + Place[] preset = curTran.getPreset(); + for (Place p : preset) { + newProcess.addPlaceToProcess(p); + } + } + processMapForOneLpn.put(procId, newProcess); + allTransitionsToLpnProcesses.put(curTran, newProcess); + } + else { + LpnProcess curProcess = processMapForOneLpn.get(procId); + curProcess.addTranToProcess(curTran); + if (curTran.getPreset() != null) { + if (curProcess.getStateMachineFlag() + && (curTran.getPreset().length > 1 + || curTran.getPostset().length > 1)) { + curProcess.setStateMachineFlag(false); + } + Place[] preset = curTran.getPreset(); + for (Place p : preset) { + curProcess.addPlaceToProcess(p); + } + } + allTransitionsToLpnProcesses.put(curTran, curProcess); + } + } + } + HashMap tranFiringFreq = null; +// if (Options.getUseDependentQueue()) + tranFiringFreq = new HashMap(allTransitions.keySet().size()); + // Build conjuncts for each transition's enabling condition first before dealing with dependency and enable sets. + for (int lpnIndex=0; lpnIndex peakTotalMem) + peakTotalMem = curTotalMem; + + if (curUsedMem > peakUsedMem) + peakUsedMem = curUsedMem; + + if (stateStack.size() > max_stack_depth) + max_stack_depth = stateStack.size(); + + iterations++; + if (Options.getDebugMode()) { + System.out.println("~~~~~~~~~~~ loop " + iterations + " begins ~~~~~~~~~~~"); + } + if (iterations % 100000 == 0) { + System.out.println("---> #iteration " + iterations + + "> # LPN transition firings: " + tranFiringCnt + + ", # of prjStates found: " + totalStates + + ", stack_depth: " + stateStack.size() + + " used memory: " + (float) curUsedMem / 1000000 + + " free memory: " + + (float) Runtime.getRuntime().freeMemory() / 1000000); + } + State[] curStateArray = stateStackTop.toStateArray(); //stateStack.peek(); + LinkedList curStrongStubbornTrans = lpnTranStack.peek(); + firedFailure = failureTranIsEnabled(curStrongStubbornTrans); // Null means no failure. +// if(firedFailure != null){ +// return null; +// } + if(firedFailure != null){ + System.out.println("**** Failure transition " + firedFailure.getFullLabel() + " is enabled. Exit."); + failure = true; + break main_while_loop; + } + + if (curStrongStubbornTrans.size() == 0) { + lpnTranStack.pop(); + prjStateSet.add(stateStackTop); + stateStack.remove(stateStackTop); + stateStackTop = stateStackTop.getFather(); + if (Options.getDebugMode()) { + System.out.println("+++++++ Pop trans off lpnTranStack ++++++++"); + printTranStack(lpnTranStack, "####### lpnTranStack #########"); + +// System.out.println("####### prjStateSet #########"); +// printPrjStateSet(prjStateSet); + } + continue; + } + + Transition firedTran = curStrongStubbornTrans.removeLast(); + if (Options.getDebugMode()) { + System.out.println("#################################"); + System.out.println("Fired Transition: " + firedTran.getFullLabel()); + System.out.println("#################################"); + } + Integer freq = tranFiringFreq.get(firedTran) + 1; + tranFiringFreq.put(firedTran, freq); +// if (Options.getDebugMode()) { +// System.out.println("~~~~~~tranFiringFreq~~~~~~~"); +// //printHashMap(tranFiringFreq, sgList); +// } + State[] nextStateArray = sgList[firedTran.getLpn().getLpnIndex()].fire(sgList, curStateArray, firedTran); + tranFiringCnt++; + PrjState nextPrjState; + if (!Options.getMarkovianModelFlag()) + nextPrjState = new PrjState(nextStateArray); + else + nextPrjState = new ProbGlobalState(nextStateArray); + + // Check if the firedTran causes disabling error or deadlock. + // TODO: (temp) Stochastic model does not need disabling error? + if (Options.getReportDisablingError() && !Options.getMarkovianModelFlag()) { + for (int i=0; i nextStrongStubbornSet = new HashSet(); + HashSet curStrongStubbornSet = new HashSet(); + for (Transition t : nextStrongStubbornTrans) + nextStrongStubbornSet.add(t); + for (State curSt : curStateArray) { + if (curSt.getStateGraph().getEnabledSetTbl().get(curSt) != null) { + curStrongStubbornSet.addAll(curSt.getStateGraph().getEnabledSetTbl().get(curSt)); + } + + } + LpnTranList newCurStateStrongStubborn = new LpnTranList(); + newCurStateStrongStubborn = computeCycleClosingTrans(curStateArray, nextStateArray, + tranFiringFreq, sgList, nextStrongStubbornSet, curStrongStubbornSet, firedTran); + if (newCurStateStrongStubborn != null && !newCurStateStrongStubborn.isEmpty()) { + if (Options.getDebugMode()) { + printStateArray(stateStackTop.toStateArray(), "%%%%%%% Add state to stateStack %%%%%%%%"); + System.out.println("stateStackTop: "); + printStateArray(stateStackTop.toStateArray(), "stateStackTop"); + System.out.println("nextStateMap for stateStackTop: "); + //printNextGlobalStateMap(nextPrjState.getNextStateMap()); + } + lpnTranStack.peek().addAll(newCurStateStrongStubborn); +// lpnTranStack.push(newNextPersistent); +// stateStackTop.setChild(nextPrjStInStateSet); +// nextPrjStInStateSet.setFather(stateStackTop); +// stateStackTop = nextPrjStInStateSet; +// stateStack.add(stateStackTop); + updateLocalStrongStubbornSetTbl(newCurStateStrongStubborn, sgList, nextStateArray); + if (Options.getDebugMode()) { + printTransList(newCurStateStrongStubborn, "+++++++ Push these trans onto lpnTranStack @ Cycle Closing ++++++++"); + printTranStack(lpnTranStack, "******* lpnTranStack ***************"); + } + } + } + } + else { + updateLocalStrongStubbornSetTbl(nextStrongStubbornTrans, sgList, nextStateArray); + } + } + } + double totalStateCnt = prjStateSet.size(); + System.out.println("---> final numbers: # LPN transition firings: " + tranFiringCnt + + ", # of prjStates found: " + totalStateCnt + + ", max_stack_depth: " + max_stack_depth + + ", peak total memory: " + peakTotalMem / 1000000 + " MB" + + ", peak used memory: " + peakUsedMem / 1000000 + " MB"); + + if (Options.getOutputLogFlag()) + writePerformanceResultsToLogFile(true, tranFiringCnt, totalStateCnt, peakTotalMem / 1000000, peakUsedMem / 1000000); + if (Options.getOutputSgFlag()) { + System.out.println("outputSGPath = " + Options.getPrjSgPath()); // + drawGlobalStateGraph(initPrjState, prjStateSet); + } + return prjStateSet; + } + + /** + * Print the prjState's label. The label consists of full labels of each local state that composes it. + * @param prjState + * @return + */ + private static String printGlobalStateLabel(PrjState prjState) { + String prjStateLabel = ""; + for (State local : prjState.toStateArray()) { + prjStateLabel += local.getFullLabel() + "_"; + } + return prjStateLabel.substring(0, prjStateLabel.lastIndexOf("_")); + } + + + private static String printGlobalStateLabel(State[] nextStateArray) { + String prjStateLabel = ""; + for (State local : nextStateArray) { + prjStateLabel += local.getFullLabel() + "_"; + } + return prjStateLabel.substring(0, prjStateLabel.lastIndexOf("_")); + } + + private void writePerformanceResultsToLogFile(boolean isPOR, int tranFiringCnt, double totalStateCnt, + double peakTotalMem, double peakUsedMem) { + try { + String fileName = null; + if (isPOR) { + fileName = Options.getPrjSgPath() + separator + Options.getLogName() + "_" + Options.getPOR() + "_" + + Options.getCycleClosingMthd() + "_" + Options.getCycleClosingStrongStubbornMethd() + ".log"; + } + else + fileName = Options.getPrjSgPath() + Options.getLogName() + "_full" + ".log"; + BufferedWriter out = new BufferedWriter(new FileWriter(fileName)); + out.write("tranFiringCnt" + "\t" + "prjStateCnt" + "\t" + "maxStackDepth" + "\t" + "peakTotalMem(MB)" + "\t" + "peakUsedMem(MB)\n"); + out.write(tranFiringCnt + "\t" + totalStateCnt + "\t" + max_stack_depth + "\t" + peakTotalMem + "\t" + + peakUsedMem + "\n"); + out.close(); + } + catch (Exception e) { + e.printStackTrace(); + System.err.println("Error producing performance results."); + } + } + + private static void printTranStack(Stack> lpnTranStack, String title) { + if (title != null) + System.out.println(title); + for (int i=0; i tranList = lpnTranStack.get(i); + for (int j=0; j nextStateMap) { +// for (Transition t: nextStateMap.keySet()) { +// System.out.println(t.getFullLabel() + " -> "); +// State[] stateArray = nextStateMap.get(t).getStateArray(); +// for (int i=0; i newNextPersistent) { +// LpnTranList newNextPersistentTrans = new LpnTranList(); +// for (Transition lpnTran : newNextPersistent) { +// newNextPersistentTrans.add(lpnTran); +// } +// return newNextPersistentTrans; +// } + + private LpnTranList computeCycleClosingTrans(State[] curStateArray, State[] nextStateArray, HashMap tranFiringFreq, + StateGraph[] sgList, HashSet nextStateStrongStubbornSet, HashSet curStateStrongStubbornSet, Transition firedTran) { + for (State s : nextStateArray) + if (s == null) + throw new NullPointerException(); + String cycleClosingMthd = Options.getCycleClosingMthd(); + LpnTranList newCurStateStrongStubbornSet = new LpnTranList(); + HashSet nextStateEnabled = new HashSet(); + HashSet curStateEnabled = new HashSet(); + for (int lpnIndex=0; lpnIndex curStateReduced = setSubstraction(curStateEnabled, curStateStrongStubbornSet); + HashSet oldNextStateStrongStubbornSet = new HashSet(); + DependentSetComparator depComp = new DependentSetComparator(tranFiringFreq, sgList.length-1); + PriorityQueue dependentSetQueue = new PriorityQueue(nextStateEnabled.size(), depComp); + if (Options.getDebugMode()) + printStateArray(nextStateArray,"******* nextStateArray *******"); + for (int lpnIndex=0; lpnIndex < sgList.length; lpnIndex++) { + if (sgList[lpnIndex].getEnabledSetTbl().get(nextStateArray[lpnIndex]) != null) { + LpnTranList oldLocalNextStateStrongStubbornTrans = sgList[lpnIndex].getEnabledSetTbl().get(nextStateArray[lpnIndex]); + if (Options.getDebugMode()) { + printTransList(oldLocalNextStateStrongStubbornTrans, "oldLocalNextStateStrongStubbornTrans"); + } + for (Transition oldLocalTran : oldLocalNextStateStrongStubbornTrans) + oldNextStateStrongStubbornSet.add(oldLocalTran); + } + + } + HashSet ignored = setSubstraction(curStateReduced, oldNextStateStrongStubbornSet); + if (Options.getDebugMode()) { + printIntegerSet(ignored, "------ Ignored transition(s) at global state " + printGlobalStateLabel(nextStateArray)); + } + boolean isCycleClosingStrongStubbornComputation = true; + for (Transition seed : ignored) { + HashSet dependent = new HashSet(); + dependent = computeDependent(curStateArray,seed,dependent,nextStateEnabled,isCycleClosingStrongStubbornComputation); + if (Options.getDebugMode()) { + printIntegerSet(dependent, "------ dependent set for ignored transition " + seed.getFullLabel() + " ------"); + } + // TODO: Is this still necessary? + // boolean dependentOnlyHasDummyTrans = true; + // for (LpnTransitionPair dependentTran : dependent) { + // dependentOnlyHasDummyTrans = dependentOnlyHasDummyTrans + // && isDummyTran(sgList[dependentTran.getLpnIndex()].getLpn().getTransition(dependentTran.getTranIndex()).getName()); + // } + // if ((newNextPersistent.size() == 0 || dependent.size() < newNextPersistent.size()) && !dependentOnlyHasDummyTrans) + // newNextPersistent = (HashSet) dependent.clone(); + // DependentSet dependentSet = new DependentSet(newNextPersistent, seed, + // isDummyTran(sgList[seed.getLpnIndex()].getLpn().getTransition(seed.getTranIndex()).getName())); + // _______________________________________________________________________ + DependentSet dependentSet = new DependentSet(dependent, seed, isDummyTran(seed.getLabel())); + dependentSetQueue.add(dependentSet); + } + cachedNecessarySets.clear(); + if (!dependentSetQueue.isEmpty()) { + // System.out.println("depdentSetQueue is NOT empty."); + // newNextPersistent = dependentSetQueue.poll().getDependent(); + // ************************** + // TODO: Will newNextTmp - oldNextStrongStubborn be safe? + HashSet strongStubbornIgnoredTrans = dependentSetQueue.poll().getDependent(); + //newNextPersistent = setSubstraction(newNextPersistentTmp, oldNextPersistent); + newCurStateStrongStubbornSet.addAll(setSubstraction(strongStubbornIgnoredTrans, oldNextStateStrongStubbornSet)); + // ************************** + updateLocalStrongStubbornSetTbl(newCurStateStrongStubbornSet, sgList, curStateArray); + } + if (Options.getDebugMode()) { + printTransList(newCurStateStrongStubbornSet, "----- Ignored trans needed to add to global state " + printGlobalStateLabel(curStateArray) + " ------"); + System.out.println("******** behavioral: end of cycle closing check *****"); + } + } + else if (cycleClosingMthd.equals("state_search")) { + // TODO: complete cycle closing check for state search. + } + return newCurStateStrongStubbornSet; + } + + + private static void updateLocalStrongStubbornSetTbl(LpnTranList nextStrongStubbornTrans, + StateGraph[] sgList, State[] curStateArray) { + // Persistent set at each state is stored in the enabledSetTbl in each state graph. + for (Transition tran : nextStrongStubbornTrans) { + int lpnIndex = tran.getLpn().getLpnIndex(); + State nextState = curStateArray[lpnIndex]; + LpnTranList curStrongStubbornTrans = sgList[lpnIndex].getEnabledSetTbl().get(nextState); + if (curStrongStubbornTrans != null) { + if (!curStrongStubbornTrans.contains(tran)) + curStrongStubbornTrans.add(tran); + } + else { + LpnTranList newLpnTranList = new LpnTranList(); + newLpnTranList.add(tran); + sgList[lpnIndex].getEnabledSetTbl().put(curStateArray[lpnIndex], newLpnTranList); + } + } + if (Options.getDebugMode()) { + printStrongStubbornSetTbl(sgList); + } + } + +// private void printPrjStateSet(StateSetInterface prjStateSet) { +// for (PrjState curGlobal : prjStateSet) { +// State[] curStateArray = curGlobal.toStateArray(); +// printStateArray(curStateArray, null); +// System.out.println("-------------"); +// } +// } + +// /** +// * This method performs first-depth search on multiple LPNs and applies partial order reduction technique with the trace-back. +// * @param sgList +// * @param initStateArray +// * @param cycleClosingMthdIndex +// * @return +// */ +// public StateGraph[] search_dfsPORrefinedCycleRule(final StateGraph[] sgList, final State[] initStateArray, int cycleClosingMthdIndex) { +// System.out.println("---> calling function search_dfsPORrefinedCycleRule"); +// if (cycleClosingMthdIndex == 1) +// System.out.println("---> POR with behavioral analysis"); +// else if (cycleClosingMthdIndex == 2) +// System.out.println("---> POR with behavioral analysis and state trace-back"); +// else if (cycleClosingMthdIndex == 4) +// System.out.println("---> POR with Peled's cycle condition"); +// double peakUsedMem = 0; +// double peakTotalMem = 0; +// boolean failure = false; +// int tranFiringCnt = 0; +// int totalStates = 1; +// int numLpns = sgList.length; +// +// HashSet stateStack = new HashSet(); +// Stack> lpnTranStack = new Stack>(); +// Stack curIndexStack = new Stack(); +// +// HashSet prjStateSet = new HashSet(); +// PrjState initPrjState = new PrjState(initStateArray); +// prjStateSet.add(initPrjState); +// +// PrjState stateStackTop = initPrjState; +// System.out.println("%%%%%%% Add states to stateStack %%%%%%%%"); +// printStateArray(stateStackTop.toStateArray()); +// stateStack.add(stateStackTop); + +// // Prepare static pieces for POR +// HashMap> staticSetsMap = new HashMap>(); +// Transition[] allTransitions = sgList[0].getLpn().getAllTransitions(); +// HashMap tmpMap = new HashMap(); +// HashMap tranFiringFreq = new HashMap(allTransitions.length); +// for (Transition curTran: allTransitions) { +// StaticSets curStatic = new StaticSets(sgList[0].getLpn(), curTran, allTransitions); +// curStatic.buildDisableSet(); +// curStatic.buildEnableSet(); +// curStatic.buildModifyAssignSet(); +// tmpMap.put(curTran.getIndex(), curStatic); +// tranFiringFreq.put(curTran.getIndex(), 0); +// } +// staticSetsMap.put(sgList[0].getLpn().getLpnIndex(), tmpMap); +// printStaticSetMap(staticSetsMap); + + +// System.out.println("call getPersistent on initStateArray at 0: "); +// boolean init = true; +// PersistentxSet initPersistent = new PersistentSet(); +// initPersistent = sgList[0].getPersistent(initStateArray[0], staticSetsMap, init, tranFiringFreq); +// HashMap initEnabledSetTbl = (HashMap) sgList[0].copyEnabledSetTbl(); +// lpnTranStack.push(initPersistent.getPersistentSet()); +// curIndexStack.push(0); + +// System.out.println("+++++++ Push trans onto lpnTranStack ++++++++"); +// printTransitionSet((LpnTranList) initPersistent.getPersistentSet(), ""); +// +// main_while_loop: while (failure == false && stateStack.size() != 0) { +// System.out.println("$$$$$$$$$$$ loop begins $$$$$$$$$$"); +// long curTotalMem = Runtime.getRuntime().totalMemory(); +// long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); +// +// if (curTotalMem > peakTotalMem) +// peakTotalMem = curTotalMem; +// +// if (curUsedMem > peakUsedMem) +// peakUsedMem = curUsedMem; +// +// if (stateStack.size() > max_stack_depth) +// max_stack_depth = stateStack.size(); +// +// iterations++; +// if (iterations % 100000 == 0) { +// System.out.println("---> #iteration " + iterations +// + "> # LPN transition firings: " + tranFiringCnt +// + ", # of prjStates found: " + totalStates +// + ", stack_depth: " + stateStack.size() +// + " used memory: " + (float) curUsedMem / 1000000 +// + " free memory: " +// + (float) Runtime.getRuntime().freeMemory() / 1000000); +// } +// +// State[] curStateArray = stateStackTop.toStateArray(); //stateStack.peek(); +// int curIndex = curIndexStack.peek(); +//// System.out.println("curIndex = " + curIndex); +// //PersistentSet curPersistent = new PersistentSet(); +// //LinkedList curPersistentTrans = curPersistent.getPersistentSet(); +// LinkedList curPersistentTrans = lpnTranStack.peek(); +// +//// System.out.println("------- curStateArray ----------"); +//// printStateArray(curStateArray); +//// System.out.println("+++++++ curPersistent trans ++++++++"); +//// printTransLinkedList(curPersistentTrans); +// +// // If all enabled transitions of the current LPN are considered, +// // then consider the next LPN +// // by increasing the curIndex. +// // Otherwise, if all enabled transitions of all LPNs are considered, +// // then pop the stacks. +// if (curPersistentTrans.size() == 0) { +// lpnTranStack.pop(); +//// System.out.println("+++++++ Pop trans off lpnTranStack ++++++++"); +// curIndexStack.pop(); +//// System.out.println("+++++++ Pop index off curIndexStack ++++++++"); +// curIndex++; +//// System.out.println("curIndex = " + curIndex); +// while (curIndex < numLpns) { +// System.out.println("call getEnabled on curStateArray at 1: "); + +// LpnTranList tmpPersistentTrans = (LpnTranList) (sgList[curIndex].getPersistent(curStateArray[curIndex], staticSetsMap, init, tranFiringFreq)).getPersistentSet(); +// curPersistentTrans = tmpPersistentTrans.clone(); +// //printTransitionSet(curEnabled, "curEnabled set"); +// if (curPersistentTrans.size() > 0) { +// System.out.println("+++++++ Push trans onto lpnTranStack ++++++++"); +// printTransLinkedList(curPersistentTrans); +// lpnTranStack.push(curPersistentTrans); +// curIndexStack.push(curIndex); +// printIntegerStack("curIndexStack after push 1", curIndexStack); +// break; +// } +// curIndex++; +// } +// } +// if (curIndex == numLpns) { +// prjStateSet.add(stateStackTop); +// System.out.println("%%%%%%% Remove stateStackTop from stateStack %%%%%%%%"); +// printStateArray(stateStackTop.toStateArray()); +// stateStack.remove(stateStackTop); +// stateStackTop = stateStackTop.getFather(); +// continue; +// } +// +// Transition firedTran = curPersistentTrans.removeLast(); +// System.out.println("###################"); +// System.out.println("Fired transition: " + firedTran.getName()); +// System.out.println("###################"); + +// Integer freq = tranFiringFreq.get(firedTran.getIndex()) + 1; +// tranFiringFreq.put(firedTran.getIndex(), freq); +// System.out.println("~~~~~~tranFiringFreq~~~~~~~"); +// printHashMap(tranFiringFreq, allTransitions); +// State[] nextStateArray = sgList[curIndex].fire(sgList, curStateArray, firedTran); +// tranFiringCnt++; + + // Check if the firedTran causes disabling error or deadlock. +// @SuppressWarnings("unchecked") +// LinkedList[] curPersistentArray = new LinkedList[numLpns]; +// @SuppressWarnings("unchecked") +// LinkedList[] nextPersistentArray = new LinkedList[numLpns]; +// boolean updatedPersistentDueToCycleRule = false; +// for (int i = 0; i < numLpns; i++) { +// StateGraph sg_tmp = sgList[i]; +// System.out.println("call getPersistent on curStateArray at 2: i = " + i); +// PersistentSet PersistentList = new PersistentSet(); +// if (init) { +// PersistentList = initPersistent; +// sg_tmp.setEnabledSetTbl(initEnabledSetTbl); +// init = false; +// } +// else +// PersistentList = sg_tmp.getPersistent(curStateArray[i], staticSetsMap, init, tranFiringFreq); +// curPersistentArray[i] = PersistentList.getPersistentSet(); + +// System.out.println("call getPersistentRefinedCycleRule on nextStateArray at 3: i = " + i); + +// PersistentList = sg_tmp.getPersistentRefinedCycleRule(curStateArray[i], nextStateArray[i], staticSetsMap, stateStack, stateStackTop, init, cycleClosingMthdIndex, i, tranFiringFreq); +// nextPersistentArray[i] = PersistentList.getPersistentSet(); +// if (!updatedPersistentDueToCycleRule && PersistentList.getPersistentChanged()) { +// updatedPersistentDueToCycleRule = true; + +// System.out.println("-------------- curPersistentArray --------------"); +// for (LinkedList tranList : curPersistentArray) { +// printTransLinkedList(tranList); +// } +//// System.out.println("-------------- curPersistentArray --------------"); +//// for (LinkedList tranList : curPersistentArray) { +//// printTransLinkedList(tranList); +//// } +//// System.out.println("-------------- nextPersistentArray --------------"); +//// for (LinkedList tranList : nextPersistentArray) { +//// printTransLinkedList(tranList); +//// } +// Transition disabledTran = firedTran.disablingError( +// curStateArray[i].getEnabledTransitions(), nextStateArray[i].getEnabledTransitions()); +// if (disabledTran != null) { +// System.err.println("Disabling Error: " +// + disabledTran.getFullLabel() + " is disabled by " +// + firedTran.getFullLabel()); +// failure = true; +// break main_while_loop; +// } + +// } +// +// if (Analysis.deadLock(sgList, nextStateArray, staticSetsMap, init, tranFiringFreq) == true) { +// System.out.println("*** Verification failed: deadlock."); +// failure = true; +// break main_while_loop; +// } +// +// PrjState nextPrjState = new PrjState(nextStateArray); +// Boolean existingState = prjStateSet.contains(nextPrjState) || stateStack.contains(nextPrjState); +// if (existingState == true && updatedPersistentDueToCycleRule) { +// // cycle closing +// System.out.println("%%%%%%% existingSate == true %%%%%%%%"); +// stateStackTop.setChild(nextPrjState); +// nextPrjState.setFather(stateStackTop); +// stateStackTop = nextPrjState; +// stateStack.add(stateStackTop); +// System.out.println("%%%%%%% Add state to stateStack %%%%%%%%"); +// printStateArray(stateStackTop.toStateArray()); +// System.out.println("+++++++ Push trans onto lpnTranStack ++++++++"); +// printTransitionSet((LpnTranList) nextPersistentArray[0], ""); +// lpnTranStack.push((LpnTranList) nextPersistentArray[0].clone()); +// curIndexStack.push(0); +// } +// if (existingState == false) { +// System.out.println("%%%%%%% existingSate == false %%%%%%%%"); +// stateStackTop.setChild(nextPrjState); +// nextPrjState.setFather(stateStackTop); +// stateStackTop = nextPrjState; +// stateStack.add(stateStackTop); +// System.out.println("%%%%%%% Add state to stateStack %%%%%%%%"); +// printStateArray(stateStackTop.toStateArray()); +// System.out.println("+++++++ Push trans onto lpnTranStack ++++++++"); +// printTransitionSet((LpnTranList) nextPersistentArray[0], ""); +// lpnTranStack.push((LpnTranList) nextPersistentArray[0].clone()); +// curIndexStack.push(0); +// totalStates++; +// } +// } +// // end of main_while_loop +// +// double totalStateCnt = prjStateSet.size(); +// +// System.out.println("---> final numbers: # LPN transition firings: " + tranFiringCnt +// + ", # of prjStates found: " + totalStateCnt +// + ", max_stack_depth: " + max_stack_depth +// + ", peak total memory: " + peakTotalMem / 1000000 + " MB" +// + ", peak used memory: " + peakUsedMem / 1000000 + " MB"); +// +// // This currently works for a single LPN. +// return sgList; +// return null; +// } + + private void printStaticSetsMap( LPN[] lpnList) { + System.out.println("============ staticSetsMap ============"); + for (Transition lpnTranPair : staticDependency.keySet()) { + StaticDependencySets statSets = staticDependency.get(lpnTranPair); + printLpnTranPair(statSets.getSeedTran(), statSets.getDisableSet(false), "disableSet"); + for (HashSet setOneConjunctTrue : statSets.getOtherTransSetSeedTranEnablingTrue()) { + printLpnTranPair(statSets.getSeedTran(), setOneConjunctTrue, "enableBySetingEnablingTrue for one conjunct"); + } + } + } + + private static void printLpnTranPair(Transition curTran, + HashSet TransitionSet, String setName) { + System.out.println(setName + " for transition " + curTran.getFullLabel() + " is: "); + if (TransitionSet.isEmpty()) { + System.out.println("empty"); + } + else { + for (Transition lpnTranPair: TransitionSet) + System.out.print(lpnTranPair.getFullLabel() + "\n"); + System.out.println(); + } + } + +// private Transition[] assignStickyTransitions(LhpnFile lpn) { +// // allProcessTrans is a hashmap from a transition to its process color (integer). +// HashMap allProcessTrans = new HashMap(); +// // create an Abstraction object to call the divideProcesses method. +// Abstraction abs = new Abstraction(lpn); +// abs.decomposeLpnIntoProcesses(); +// allProcessTrans.putAll( +// (HashMap)abs.getTransWithProcIDs().clone()); +// HashMap processMap = new HashMap(); +// for (Iterator tranIter = allProcessTrans.keySet().iterator(); tranIter.hasNext();) { +// Transition curTran = tranIter.next(); +// Integer procId = allProcessTrans.get(curTran); +// if (!processMap.containsKey(procId)) { +// LpnProcess newProcess = new LpnProcess(procId); +// newProcess.addTranToProcess(curTran); +// if (curTran.getPreset() != null) { +// Place[] preset = curTran.getPreset(); +// for (Place p : preset) { +// newProcess.addPlaceToProcess(p); +// } +// } +// processMap.put(procId, newProcess); +// } +// else { +// LpnProcess curProcess = processMap.get(procId); +// curProcess.addTranToProcess(curTran); +// if (curTran.getPreset() != null) { +// Place[] preset = curTran.getPreset(); +// for (Place p : preset) { +// curProcess.addPlaceToProcess(p); +// } +// } +// } +// } +// +// for(Iterator processMapIter = processMap.keySet().iterator(); processMapIter.hasNext();) { +// LpnProcess curProc = processMap.get(processMapIter.next()); +// curProc.assignStickyTransitions(); +// curProc.printProcWithStickyTrans(); +// } +// return lpn.getAllTransitions(); +// } + +// private void printLpnTranPair(LhpnFile[] lpnList, Transition curTran, +// HashSet curDisable, String setName) { +// System.out.print(setName + " for " + curTran.getName() + "(" + curTran.getIndex() + ")" + " is: "); +// if (curDisable.isEmpty()) { +// System.out.println("empty"); +// } +// else { +// for (Transition lpnTranPair: curDisable) { +// System.out.print("(" + lpnList[lpnTranPair.getLpnIndex()].getLabel() +// + ", " + lpnList[lpnTranPair.getLpnIndex()].getAllTransitions()[lpnTranPair.getTranIndex()].getName() + ")," + "\t"); +// } +// System.out.print("\n"); +// } +// } + + /** + * Return the set of all LPN transitions that are enabled in 'state'. + * The enabledSetTbl (for each StateGraph obj) stores the strong stubborn set for each state of each LPN. + * @param stateArray + * @param prjStateSet + * @param enable + * @param disableByStealingToken + * @param disable + * @param sgList + * @return + */ + private LpnTranList buildStrongStubbornSet(State[] curStateArray, State[] nextStateArray, + HashMap tranFiringFreq, StateGraph[] sgList, LPN[] lpnList, + StateSetInterface prjStateSet, PrjState stateStackTop, Transition lastFiredTran) { + State[] stateArray = null; + if (nextStateArray == null) + stateArray = curStateArray; + else + stateArray = nextStateArray; + for (State s : stateArray) + if (s == null) + throw new NullPointerException(); + LpnTranList strongStubbornSet = new LpnTranList(); + HashSet curEnabled = new HashSet(); + for (int lpnIndex=0; lpnIndex ready = curEnabled; + HashSet ready = computeStrongStubbornSet(stateArray, curEnabled, tranFiringFreq, sgList); + if (Options.getDebugMode()) { + System.out.println("******* End POR *******"); + printIntegerSet(ready, "Strong Stubborn Set"); + System.out.println("********************"); + } + + // ************* Priority: transition fired less times first ************* + if (tranFiringFreq != null) { + LinkedList readyList = new LinkedList(); + for (Transition inReady : ready) { + readyList.add(inReady); + } + mergeSort(readyList, tranFiringFreq); + for (Transition inReady : readyList) { + strongStubbornSet.addFirst(inReady); + } + } + else { + for (Transition tran : ready) { + strongStubbornSet.add(tran); + } + } + return strongStubbornSet; + } + + private LinkedList mergeSort(LinkedList array, HashMap tranFiringFreq) { + if (array.size() == 1) + return array; + int middle = array.size() / 2; + LinkedList left = new LinkedList(); + LinkedList right = new LinkedList(); + for (int i=0; i merge(LinkedList left, + LinkedList right, HashMap tranFiringFreq) { + LinkedList result = new LinkedList(); + while (left.size() > 0 || right.size() > 0) { + if (left.size() > 0 && right.size() > 0) { + if (tranFiringFreq.get(left.peek()) <= tranFiringFreq.get(right.peek())) { + result.addLast(left.poll()); + } + else { + result.addLast(right.poll()); + } + } + else if (left.size()>0) { + result.addLast(left.poll()); + } + else if (right.size()>0) { + result.addLast(right.poll()); + } + } + return result; + } + +// /** +// * Return the set of all LPN transitions that are enabled in 'state'. The "init" flag indicates whether a transition +// * needs to be evaluated. +// * @param nextState +// * @param stateStackTop +// * @param enable +// * @param disableByStealingToken +// * @param disable +// * @param init +// * @param cycleClosingMthdIndex +// * @param lpnIndex +// * @param isNextState +// * @return +// */ +// private LpnTranList getPersistentRefinedCycleRule(State[] curStateArray, State[] nextStateArray, HashMap staticSetsMap, +// boolean init, HashMap tranFiringFreq, StateGraph[] sgList, +// HashSet stateStack, PrjState stateStackTop) { +// PersistentSet nextPersistent = new PersistentSet(); +// if (nextState == null) { +// throw new NullPointerException(); +// } +// if(PersistentSetTbl.containsKey(nextState) == true && stateOnStack(nextState, stateStack)) { +// System.out.println("~~~~~~~ existing state in enabledSetTbl and on stateStack: S" + nextState.getIndex() + "~~~~~~~~"); +// printTransitionSet((LpnTranList)PersistentSetTbl.get(nextState), "Old Persistent at this state: "); +// // Cycle closing check +// LpnTranList nextPersistentTransOld = (LpnTranList) nextPersistent.getPersistentSet(); +// nextPersistentTransOld = PersistentSetTbl.get(nextState); +// LpnTranList curPersistentTrans = PersistentSetTbl.get(curState); +// LpnTranList curReduced = new LpnTranList(); +// LpnTranList curEnabled = curState.getEnabledTransitions(); +// for (int i=0; i curEnabledIndicies = new HashSet(); +// for (int i=0; i transToAddIndices = new HashSet(); +// for (int i=0; i nextPersistentNewIndices = (HashSet) curEnabledIndicies.clone(); +// for (Integer tranToAdd : transToAddIndices) { +// HashSet dependent = new HashSet(); +// //Transition enabledTransition = this.lpn.getAllTransitions()[tranToAdd]; +// dependent = computeDependent(curState,tranToAdd,dependent,curEnabledIndicies,staticMap); +// // printIntegerSet(dependent, "dependent set for enabled transition " + this.lpn.getAllTransitions()[enabledTran]); +// +// boolean dependentOnlyHasDummyTrans = true; +// for (Integer curTranIndex : dependent) { +// Transition curTran = this.lpn.getAllTransitions()[curTranIndex]; +// dependentOnlyHasDummyTrans = dependentOnlyHasDummyTrans && isDummyTran(curTran.getName()); +// } +// if (dependent.size() < nextPersistentNewIndices.size() && !dependentOnlyHasDummyTrans) +// nextPersistentNewIndices = (HashSet) dependent.clone(); +// if (nextPersistentNewIndices.size() == 1) +// break; +// } +// LpnTranList nextPersistentNew = new LpnTranList(); +// for (Integer nextPersistentNewIndex : nextPersistentNewIndices) { +// nextPersistentNew.add(this.getLpn().getTransition(nextPersistentNewIndex)); +// } +// LpnTranList transToAdd = getSetSubtraction(nextPersistentNew, nextPersistentTransOld); +// boolean allTransToAddFired = false; +// if (cycleClosingMthdIndex == 2) { +// // For every transition t in transToAdd, if t was fired in the any state on stateStack, there is no need to put it to the new Persistent of nextState. +// if (transToAdd != null) { +// LpnTranList transToAddCopy = transToAdd.copy(); +// HashSet stateVisited = new HashSet(); +// stateVisited.add(nextState.getIndex()); +// allTransToAddFired = allTransToAddFired(transToAddCopy, +// allTransToAddFired, stateVisited, stateStackTop, lpnIndex); +// } +// } +// // Update the old Persistent of the next state +// if (!allTransToAddFired || cycleClosingMthdIndex == 1) { +// nextPersistent.getPersistentSet().clear(); +// nextPersistent.getPersistentSet().addAll(transToAdd); +// PersistentSetTbl.get(nextState).addAll(transToAdd); +// printTransitionSet(nextPersistentNew, "nextPersistentNew:"); +// printTransitionSet(transToAdd, "transToAdd:"); +// System.out.println("((((((((((((((((((((()))))))))))))))))))))"); +// } +// if (cycleClosingMthdIndex == 4) { +// nextPersistent.getPersistentSet().clear(); +// nextPersistent.getPersistentSet().addAll(overlyReducedTrans); +// PersistentSetTbl.get(nextState).addAll(overlyReducedTrans); +// printTransitionSet(nextPersistentNew, "nextPersistentNew:"); +// printTransitionSet(transToAdd, "transToAdd:"); +// System.out.println("((((((((((((((((((((()))))))))))))))))))))"); +// } +// } +// // enabledSetTble stores the Persistent set at curState. +// // The fully enabled set at each state is stored in the tranVector in each state. +// return (PersistentSet) nextPersistent; +// } + + +// +// for (State s : nextStateArray) +// if (s == null) +// throw new NullPointerException(); +// cachedNecessarySets.clear(); +// String cycleClosingMthd = Options.getCycleClosingMthd(); +// PersistentSet nextPersistent = new PersistentSet(); +// HashSet nextEnabled = new HashSet(); +//// boolean allEnabledAreSticky = false; +// for (int lpnIndex=0; lpnIndex dependentSetQueue = new PriorityQueue(nextEnabled.size(), depComp); +// LhpnFile[] lpnList = new LhpnFile[sgList.length]; +// for (int i=0; i transToAddMap = new HashMap(); +// Integer cycleClosingLpnIndex = -1; +// for (int lpnIndex=0; lpnIndex ignored = new HashSet(); +// for (int i=0; i newNextPersistent = (HashSet) nextEnabled.clone(); +// if (cycleClosingMthd.toLowerCase().equals("behavioral")) { +// for (Transition seed : ignored) { +// HashSet dependent = new HashSet(); +// dependent = computeDependent(nextStateArray,seed,dependent,nextEnabled,staticSetsMap, lpnList); +// printIntegerSet(dependent, sgList, "dependent set for ignored transition " + sgList[seed.getLpnIndex()].getLpn().getLabel() +// + "(" + sgList[seed.getLpnIndex()].getLpn().getTransition(seed.getTranIndex()).getName() + ")"); +// +// boolean dependentOnlyHasDummyTrans = true; +// for (Transition dependentTran : dependent) { +// dependentOnlyHasDummyTrans = dependentOnlyHasDummyTrans +// && isDummyTran(sgList[dependentTran.getLpnIndex()].getLpn().getTransition(dependentTran.getTranIndex()).getName()); +// } +// if (dependent.size() < newNextPersistent.size() && !dependentOnlyHasDummyTrans) +// newNextPersistent = (HashSet) dependent.clone(); +//// if (nextPersistentNewIndices.size() == 1) +//// break; +// DependentSet dependentSet = new DependentSet(newNextPersistent, seed, +// isDummyTran(sgList[seed.getLpnIndex()].getLpn().getTransition(seed.getTranIndex()).getName())); +// dependentSetQueue.add(dependentSet); +// LpnTranList newLocalNextPersistentTrans = new LpnTranList(); +// for (Transition tran : newNextPersistent) { +// if (tran.getLpnIndex() == lpnIndex) +// newLocalNextPersistentTrans.add(sgList[lpnIndex].getLpn().getTransition(tran.getTranIndex())); +// } +// LpnTranList transToAdd = getSetSubtraction(newLocalNextPersistentTrans, oldLocalNextPersistentTrans); +// transToAddMap.put(seed, transToAdd); +// } +// } +// else if (cycleClosingMthd.toLowerCase().equals("state_search")) { +// // For every transition t in ignored, if t was fired in any state on stateStack, there is no need to put it to the new Persistent of nextState. +// HashSet stateVisited = new HashSet(); +// stateVisited.add(nextState.getIndex()); +// LpnTranList trulyIgnoredTrans = ignoredTrans.copy(); +// trulyIgnoredTrans = allIgnoredTransFired(trulyIgnoredTrans, stateVisited, stateStackTop, lpnIndex, sgList[lpnIndex]); +// if (!trulyIgnoredTrans.isEmpty()) { +// HashSet trulyIgnored = new HashSet(); +// for (Transition tran : trulyIgnoredTrans) { +// trulyIgnored.add(new Transition(tran.getLpn().getLpnIndex(), tran.getIndex())); +// } +// for (Transition seed : trulyIgnored) { +// HashSet dependent = new HashSet(); +// dependent = computeDependent(nextStateArray,seed,dependent,nextEnabled,staticSetsMap, lpnList); +// printIntegerSet(dependent, sgList, "dependent set for trulyIgnored transition " + sgList[seed.getLpnIndex()].getLpn().getLabel() +// + "(" + sgList[seed.getLpnIndex()].getLpn().getTransition(seed.getTranIndex()).getName() + ")"); +// +// boolean dependentOnlyHasDummyTrans = true; +// for (Transition dependentTran : dependent) { +// dependentOnlyHasDummyTrans = dependentOnlyHasDummyTrans +// && isDummyTran(sgList[dependentTran.getLpnIndex()].getLpn().getTransition(dependentTran.getTranIndex()).getName()); +// } +// if (dependent.size() < newNextPersistent.size() && !dependentOnlyHasDummyTrans) +// newNextPersistent = (HashSet) dependent.clone(); +// DependentSet dependentSet = new DependentSet(newNextPersistent, seed, +// isDummyTran(sgList[seed.getLpnIndex()].getLpn().getTransition(seed.getTranIndex()).getName())); +// dependentSetQueue.add(dependentSet); +// LpnTranList newLocalNextPersistentTrans = new LpnTranList(); +// for (Transition tran : newNextPersistent) { +// if (tran.getLpnIndex() == lpnIndex) +// newLocalNextPersistentTrans.add(sgList[lpnIndex].getLpn().getTransition(tran.getTranIndex())); +// } +// LpnTranList transToAdd = getSetSubtraction(newLocalNextPersistentTrans, oldLocalNextPersistentTrans); +// transToAddMap.put(seed, transToAdd); +// } +// } +// else { // All ignored transitions were fired before. It is safe to close the current cycle. +// HashSet oldLocalNextPersistent = new HashSet(); +// for (Transition tran : oldLocalNextPersistentTrans) +// oldLocalNextPersistent.add(new Transition(tran.getLpn().getLpnIndex(), tran.getIndex())); +// for (Transition seed : oldLocalNextPersistent) { +// HashSet dependent = new HashSet(); +// dependent = computeDependent(nextStateArray,seed,dependent,nextEnabled,staticSetsMap, lpnList); +// printIntegerSet(dependent, sgList, "dependent set for transition in oldNextPersistent is " + sgList[seed.getLpnIndex()].getLpn().getLabel() +// + "(" + sgList[seed.getLpnIndex()].getLpn().getTransition(seed.getTranIndex()).getName() + ")"); +// boolean dependentOnlyHasDummyTrans = true; +// for (Transition dependentTran : dependent) { +// dependentOnlyHasDummyTrans = dependentOnlyHasDummyTrans +// && isDummyTran(sgList[dependentTran.getLpnIndex()].getLpn().getTransition(dependentTran.getTranIndex()).getName()); +// } +// if (dependent.size() < newNextPersistent.size() && !dependentOnlyHasDummyTrans) +// newNextPersistent = (HashSet) dependent.clone(); +// DependentSet dependentSet = new DependentSet(newNextPersistent, seed, +// isDummyTran(sgList[seed.getLpnIndex()].getLpn().getTransition(seed.getTranIndex()).getName())); +// dependentSetQueue.add(dependentSet); +// } +// } +// } +// } +// else { +// // oldNextPersistentTrans.containsAll(curReducedTrans) == true (safe to close the current cycle) +// HashSet newNextPersistent = (HashSet) nextEnabled.clone(); +// HashSet oldLocalNextPersistent = new HashSet(); +// for (Transition tran : oldLocalNextPersistentTrans) +// oldLocalNextPersistent.add(new Transition(tran.getLpn().getLpnIndex(), tran.getIndex())); +// for (Transition seed : oldLocalNextPersistent) { +// HashSet dependent = new HashSet(); +// dependent = computeDependent(nextStateArray,seed,dependent,nextEnabled,staticSetsMap, lpnList); +// printIntegerSet(dependent, sgList, "dependent set for transition in oldNextPersistent is " + sgList[seed.getLpnIndex()].getLpn().getLabel() +// + "(" + sgList[seed.getLpnIndex()].getLpn().getTransition(seed.getTranIndex()).getName() + ")"); +// boolean dependentOnlyHasDummyTrans = true; +// for (Transition dependentTran : dependent) { +// dependentOnlyHasDummyTrans = dependentOnlyHasDummyTrans +// && isDummyTran(sgList[dependentTran.getLpnIndex()].getLpn().getTransition(dependentTran.getTranIndex()).getName()); +// } +// if (dependent.size() < newNextPersistent.size() && !dependentOnlyHasDummyTrans) +// newNextPersistent = (HashSet) dependent.clone(); +// DependentSet dependentSet = new DependentSet(newNextPersistent, seed, +// isDummyTran(sgList[seed.getLpnIndex()].getLpn().getTransition(seed.getTranIndex()).getName())); +// dependentSetQueue.add(dependentSet); +// } +// } +// } +// else if (cycleClosingMthd.toLowerCase().equals("strong")) { +// LpnTranList ignoredTrans = getSetSubtraction(reducedLocalTrans, oldLocalNextPersistentTrans); +// HashSet ignored = new HashSet(); +// for (int i=0; i allNewNextPersistent = new HashSet(); +// for (Transition seed : ignored) { +// HashSet newNextPersistent = (HashSet) nextEnabled.clone(); +// HashSet dependent = new HashSet(); +// dependent = computeDependent(nextStateArray,seed,dependent,nextEnabled,staticSetsMap, lpnList); +// printIntegerSet(dependent, sgList, "dependent set for transition in curLocalEnabled is " + sgList[seed.getLpnIndex()].getLpn().getLabel() +// + "(" + sgList[seed.getLpnIndex()].getLpn().getTransition(seed.getTranIndex()).getName() + ")"); +// boolean dependentOnlyHasDummyTrans = true; +// for (Transition dependentTran : dependent) { +// dependentOnlyHasDummyTrans = dependentOnlyHasDummyTrans +// && isDummyTran(sgList[dependentTran.getLpnIndex()].getLpn().getTransition(dependentTran.getTranIndex()).getName()); +// } +// if (dependent.size() < newNextPersistent.size() && !dependentOnlyHasDummyTrans) +// newNextPersistent = (HashSet) dependent.clone(); +// allNewNextPersistent.addAll(newNextPersistent); +// } +// // The strong cycle condition requires all seeds in ignored to be included in the allNewNextPersistent, as well as dependent set for each seed. +// // So each seed should have the same new Persistent set. +// for (Transition seed : ignored) { +// DependentSet dependentSet = new DependentSet(allNewNextPersistent, seed, +// isDummyTran(sgList[seed.getLpnIndex()].getLpn().getTransition(seed.getTranIndex()).getName())); +// dependentSetQueue.add(dependentSet); +// } +// } +// } +// else { // firedTran is not a cycle closing transition. Compute next Persistent. +//// if (nextEnabled.size() == 1) +//// return nextEnabled; +// System.out.println("The firedTran is NOT a cycle closing transition."); +// HashSet ready = null; +// for (Transition seed : nextEnabled) { +// System.out.println("@ partialOrderReduction, consider transition " + sgList[seed.getLpnIndex()].getLpn().getLabel() +// + "("+ sgList[seed.getLpnIndex()].getLpn().getTransition(seed.getTranIndex()) + ")"); +// HashSet dependent = new HashSet(); +// Transition enabledTransition = sgList[seed.getLpnIndex()].getLpn().getAllTransitions()[seed.getTranIndex()]; +// boolean enabledIsDummy = false; +//// if (enabledTransition.isSticky()) { +//// dependent = (HashSet) nextEnabled.clone(); +//// } +//// else { +//// dependent = computeDependent(curStateArray,seed,dependent,nextEnabled,staticMap, lpnList); +//// } +// dependent = computeDependent(curStateArray,seed,dependent,nextEnabled,staticSetsMap,lpnList); +// printIntegerSet(dependent, sgList, "dependent set for enabled transition " + sgList[seed.getLpnIndex()].getLpn().getLabel() +// + "(" + enabledTransition.getName() + ")"); +// if (isDummyTran(enabledTransition.getName())) +// enabledIsDummy = true; +// for (Transition inDependent : dependent) { +// if(inDependent.getLpnIndex() == cycleClosingLpnIndex) { +// // check cycle closing condition +// break; +// } +// } +// +// DependentSet dependentSet = new DependentSet(dependent, seed, enabledIsDummy); +// dependentSetQueue.add(dependentSet); +// } +// ready = dependentSetQueue.poll().getDependent(); +// +// } +//// // Update the old Persistent of the next state +// } +// +// +//// boolean allTransToAddFired = false; +//// if (cycleClosingMthdIndex == 2) { +//// // For every transition t in transToAdd, if t was fired in the any state on stateStack, there is no need to put it to the new Persistent of nextState. +//// if (transToAdd != null) { +//// LpnTranList transToAddCopy = transToAdd.copy(); +//// HashSet stateVisited = new HashSet(); +//// stateVisited.add(nextState.getIndex()); +//// allTransToAddFired = allTransToAddFired(transToAddCopy, +//// allTransToAddFired, stateVisited, stateStackTop, lpnIndex); +//// } +//// } +//// // Update the old Persistent of the next state +//// if (!allTransToAddFired || cycleClosingMthdIndex == 1) { +//// nextPersistent.getPersistentSet().clear(); +//// nextPersistent.getPersistentSet().addAll(transToAdd); +//// PersistentSetTbl.get(nextState).addAll(transToAdd); +//// printTransitionSet(nextPersistentNew, "nextPersistentNew:"); +//// printTransitionSet(transToAdd, "transToAdd:"); +//// System.out.println("((((((((((((((((((((()))))))))))))))))))))"); +//// } +//// if (cycleClosingMthdIndex == 4) { +//// nextPersistent.getPersistentSet().clear(); +//// nextPersistent.getPersistentSet().addAll(ignoredTrans); +//// PersistentSetTbl.get(nextState).addAll(ignoredTrans); +//// printTransitionSet(nextPersistentNew, "nextPersistentNew:"); +//// printTransitionSet(transToAdd, "transToAdd:"); +//// System.out.println("((((((((((((((((((((()))))))))))))))))))))"); +//// } +//// } +//// // enabledSetTble stores the Persistent set at curState. +//// // The fully enabled set at each state is stored in the tranVector in each state. +//// return (PersistentSet) nextPersistent; +// return null; +// } + +// private LpnTranList allIgnoredTransFired(LpnTranList ignoredTrans, +// HashSet stateVisited, PrjState stateStackEntry, int lpnIndex, StateGraph sg) { +// State state = stateStackEntry.get(lpnIndex); +// System.out.println("state = " + state.getIndex()); +// State predecessor = stateStackEntry.getFather().get(lpnIndex); +// if (predecessor != null) +// System.out.println("predecessor = " + predecessor.getIndex()); +// if (predecessor == null || stateVisited.contains(predecessor.getIndex())) { +// return ignoredTrans; +// } +// else +// stateVisited.add(predecessor.getIndex()); +// LpnTranList predecessorOldPersistent = sg.getEnabledSetTbl().get(predecessor);//enabledSetTbl.get(predecessor); +// for (Transition oldPersistentTran : predecessorOldPersistent) { +// State tmpState = sg.getNextStateMap().get(predecessor).get(oldPersistentTran); +// if (tmpState.getIndex() == state.getIndex()) { +// ignoredTrans.remove(oldPersistentTran); +// break; +// } +// } +// if (ignoredTrans.size()==0) { +// return ignoredTrans; +// } +// else { +// ignoredTrans = allIgnoredTransFired(ignoredTrans, stateVisited, stateStackEntry.getFather(), lpnIndex, sg); +// } +// return ignoredTrans; +// } + + + /** + * An iterative implement of findsg_recursive(). + * @param lpnList + * @param curLocalStateArray + * @param enabledArray + */ + + /** + * An iterative implement of findsg_recursive(). + * @param lpnList + * @param curLocalStateArray + * @param enabledArray + */ + public Stack search_dfs_noDisabling_fireOrder(final StateGraph[] lpnList, final State[] initStateArray) { + + boolean firingOrder = false; + + long peakUsedMem = 0; + long peakTotalMem = 0; + boolean failure = false; + int tranFiringCnt = 0; + int arraySize = lpnList.length; + + HashSet globalStateTbl = new HashSet(); + @SuppressWarnings("unchecked") + IndexObjMap[] lpnStateCache = new IndexObjMap[arraySize]; + //HashMap[] lpnStateCache1 = new HashMap[arraySize]; + + Stack stateStack = new Stack(); + Stack lpnTranStack = new Stack(); + + //get initial enable transition set + LpnTranList initEnabled = new LpnTranList(); + LpnTranList initFireFirst = new LpnTranList(); + LpnState[] initLpnStateArray = new LpnState[arraySize]; + for (int i = 0; i < arraySize; i++) + { + lpnStateCache[i] = new IndexObjMap(); + LinkedList enabledTrans = lpnList[i].getEnabled(initStateArray[i]); + HashSet enabledSet = new HashSet(); + if(!enabledTrans.isEmpty()) + { + for(Transition tran : enabledTrans) { + enabledSet.add(tran); + initEnabled.add(tran); + } + } + LpnState curLpnState = new LpnState(lpnList[i].getLpn(), initStateArray[i], enabledSet); + lpnStateCache[i].add(curLpnState); + initLpnStateArray[i] = curLpnState; + + } + LpnTranList[] initEnabledSet = new LpnTranList[2]; + initEnabledSet[0] = initFireFirst; + initEnabledSet[1] = initEnabled; + lpnTranStack.push(initEnabledSet); + + + stateStack.push(initLpnStateArray); + globalStateTbl.add(new PrjLpnState(initLpnStateArray)); + + main_while_loop: while (failure == false && stateStack.empty() == false) { + long curTotalMem = Runtime.getRuntime().totalMemory(); + long curUsedMem = Runtime.getRuntime().totalMemory() + - Runtime.getRuntime().freeMemory(); + + if (curTotalMem > peakTotalMem) + peakTotalMem = curTotalMem; + + if (curUsedMem > peakUsedMem) + peakUsedMem = curUsedMem; + + if (stateStack.size() > max_stack_depth) + max_stack_depth = stateStack.size(); + + iterations++; + //if(iterations>2)break; + if (iterations % 100000 == 0) + System.out.println("---> #iteration " + iterations + + "> # LPN transition firings: " + tranFiringCnt + + ", # of prjStates found: " + globalStateTbl.size() + + ", current_stack_depth: " + stateStack.size() + + ", total MDD nodes: " + mddMgr.nodeCnt() + + " used memory: " + (float) curUsedMem / 1000000 + + " free memory: " + + (float) Runtime.getRuntime().freeMemory() / 1000000); + + + LpnTranList[] curEnabled = lpnTranStack.peek(); + LpnState[] curLpnStateArray = stateStack.peek(); + + // If all enabled transitions of the current LPN are considered, + // then consider the next LPN + // by increasing the curIndex. + // Otherwise, if all enabled transitions of all LPNs are considered, + // then pop the stacks. + + if(curEnabled[0].size()==0 && curEnabled[1].size()==0){ + lpnTranStack.pop(); + stateStack.pop(); + continue; + } + + Transition firedTran = null; + if(curEnabled[0].size() != 0) + firedTran = curEnabled[0].removeFirst(); + else + firedTran = curEnabled[1].removeFirst(); + + traceCex.addLast(firedTran); + + State[] curStateArray = new State[arraySize]; + for( int i = 0; i < arraySize; i++) + curStateArray[i] = curLpnStateArray[i].getState(); + StateGraph sg = null; + for (int i=0; i[] extendedNextEnabledArray = new HashSet[arraySize]; + for (int i = 0; i < arraySize; i++) { + HashSet curEnabledSet = curLpnStateArray[i].getEnabled(); + LpnTranList nextEnabledList = lpnList[i].getEnabled(nextStateArray[i]); + HashSet nextEnabledSet = new HashSet(); + for(Transition tran : nextEnabledList) { + nextEnabledSet.add(tran); + } + + extendedNextEnabledArray[i] = nextEnabledSet; + + //non_disabling + for(Transition curTran : curEnabledSet) { + if(curTran == firedTran) + continue; + + if(nextEnabledSet.contains(curTran) == false) { + int[] nextMarking = nextStateArray[i].getMarking(); + // Not sure if the code below is correct. + int[] preset = lpnList[i].getLpn().getPresetIndex(curTran.getLabel()); + + boolean included = true; + if (preset != null && preset.length > 0) { + for (int pp : preset) { + boolean temp = false; + for (int mi = 0; mi < nextMarking.length; mi++) { + if (nextMarking[mi] == pp) { + temp = true; + break; + } + } + if (temp == false) + { + included = false; + break; + } + } + } + if(preset==null || preset.length==0 || included==true) { + extendedNextEnabledArray[i].add(curTran); + } + } + } + } + + boolean deadlock=true; + for(int i = 0; i < arraySize; i++) { + if(extendedNextEnabledArray[i].size() != 0){ + deadlock = false; + break; + } + } + + if(deadlock==true) { + failure = true; + break main_while_loop; + } + + + // Add nextPrjState into prjStateSet + // If nextPrjState has been traversed before, skip to the next + // enabled transition. + LpnState[] nextLpnStateArray = new LpnState[arraySize]; + for(int i = 0; i < arraySize; i++) { + HashSet lpnEnabledSet = new HashSet(); + for(Transition tran : extendedNextEnabledArray[i]) { + lpnEnabledSet.add(tran); + } + LpnState tmp = new LpnState(lpnList[i].getLpn(), nextStateArray[i], lpnEnabledSet); + LpnState tmpCached = (lpnStateCache[i].add(tmp)); + nextLpnStateArray[i] = tmpCached; + + } + + boolean newState = globalStateTbl.add(new PrjLpnState(nextLpnStateArray)); + + if(newState == false) { + traceCex.removeLast(); + continue; + } + + stateStack.push(nextLpnStateArray); + + LpnTranList[] nextEnabledSet = new LpnTranList[2]; + LpnTranList fireFirstTrans = new LpnTranList(); + LpnTranList otherTrans = new LpnTranList(); + + for(int i = 0; i < arraySize; i++) + { + for(Transition tran : nextLpnStateArray[i].getEnabled()) + { + if(firingOrder == true) + if(curLpnStateArray[i].getEnabled().contains(tran)) + otherTrans.add(tran); + else + fireFirstTrans.add(tran); + else + fireFirstTrans.add(tran); + } + } + + nextEnabledSet[0] = fireFirstTrans; + nextEnabledSet[1] = otherTrans; + lpnTranStack.push(nextEnabledSet); + + }// END while (stateStack.empty() == false) + + // graph.write(String.format("graph_%s_%s-tran_%s-state.gv",mode,tranFiringCnt, + // prjStateSet.size())); + System.out.println("SUMMARY: # LPN transition firings: " + + tranFiringCnt + ", # of prjStates found: " + + globalStateTbl.size() + ", max_stack_depth: " + max_stack_depth); + + /* + * by looking at stateStack, generate the trace showing the counter-exPersistent. + */ + if (failure == true) { + System.out.println("-------------------------------------------"); + System.out.println("the deadlock trace:"); + //update traceCex from stateStack +// LpnState[] cur = null; +// LpnState[] next = null; + for(Transition tran : traceCex) + System.out.println(tran.getFullLabel()); + } + + System.out.println("Modules' local states: "); + for (int i = 0; i < arraySize; i++) { + System.out.println("module " + lpnList[i].getLpn().getLabel() + ": " + + lpnList[i].reachSize()); + + } + + return null; + } + + + /** + * findsg using iterative approach based on DFS search. The states found are + * stored in MDD. + * + * When a state is considered during DFS, only one enabled transition is + * selected to fire in an iteration. + * + * @param lpnList + * @param curLocalStateArray + * @param enabledArray + * @return a linked list of a sequence of LPN transitions leading to the + * failure if it is not empty. + */ + public Stack search_dfs_mdd_1(final StateGraph[] lpnList, final State[] initStateArray) { + System.out.println("---> calling function search_dfs_mdd_1"); + + long peakUsedMem = 0; + long peakTotalMem = 0; + long peakMddNodeCnt = 0; + int memUpBound = 500; // Set an upper bound of memory in MB usage to + // trigger MDD compression. + boolean compressed = false; + boolean failure = false; + int tranFiringCnt = 0; + int totalStates = 1; + int arraySize = lpnList.length; + //int newStateCnt = 0; + + Stack stateStack = new Stack(); + Stack> lpnTranStack = new Stack>(); + Stack curIndexStack = new Stack(); + + mddNode reachAll = null; + mddNode reach = Mdd.newNode(); + + int[] localIdxArray = Analysis.getLocalStateIdxArray(lpnList, initStateArray, true); + mddMgr.add(reach, localIdxArray, compressed); + + stateStack.push(initStateArray); + LpnTranList initEnabled = lpnList[0].getEnabled(initStateArray[0]); + lpnTranStack.push(initEnabled.clone()); + curIndexStack.push(0); + + int numMddCompression = 0; + + main_while_loop: while (failure == false && stateStack.empty() == false) { + + long curTotalMem = Runtime.getRuntime().totalMemory(); + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + + if (curTotalMem > peakTotalMem) + peakTotalMem = curTotalMem; + + if (curUsedMem > peakUsedMem) + peakUsedMem = curUsedMem; + + if (stateStack.size() > max_stack_depth) + max_stack_depth = stateStack.size(); + + iterations++; + if (iterations % 100000 == 0) { + long curMddNodeCnt = mddMgr.nodeCnt(); + peakMddNodeCnt = peakMddNodeCnt > curMddNodeCnt ? peakMddNodeCnt : curMddNodeCnt; + + System.out.println("---> #iteration " + iterations + + "> # LPN transition firings: " + tranFiringCnt + + ", # of prjStates found: " + totalStates + + ", stack depth: " + stateStack.size() + + ", total MDD nodes: " + curMddNodeCnt + + " used memory: " + (float) curUsedMem / 1000000 + + " free memory: " + + (float) Runtime.getRuntime().freeMemory() / 1000000); + + if (curUsedMem >= memUpBound * 1000000) { + mddMgr.compress(reach); + numMddCompression++; + if (reachAll == null) + reachAll = reach; + else { + mddNode newReachAll = mddMgr.union(reachAll, reach); + if (newReachAll != reachAll) { + mddMgr.remove(reachAll); + reachAll = newReachAll; + } + } + mddMgr.remove(reach); + reach = Mdd.newNode(); + + if(memUpBound < 1500) + memUpBound *= numMddCompression; + } + } + + State[] curStateArray = stateStack.peek(); + int curIndex = curIndexStack.peek(); + LinkedList curEnabled = lpnTranStack.peek(); + + // If all enabled transitions of the current LPN are considered, + // then consider the next LPN + // by increasing the curIndex. + // Otherwise, if all enabled transitions of all LPNs are considered, + // then pop the stacks. + if (curEnabled.size() == 0) { + lpnTranStack.pop(); + curIndexStack.pop(); + + curIndex++; + while (curIndex < arraySize) { + LpnTranList enabledCached = (lpnList[curIndex].getEnabled(curStateArray[curIndex])); + if (enabledCached.size() > 0) { + curEnabled = enabledCached.clone(); + lpnTranStack.push(curEnabled); + curIndexStack.push(curIndex); + break; + } + curIndex++; + } + } + + if (curIndex == arraySize) { + stateStack.pop(); + continue; + } + + Transition firedTran = curEnabled.removeLast(); + State[] nextStateArray = lpnList[curIndex].fire(lpnList, curStateArray,firedTran); + tranFiringCnt++; + + // Check if the firedTran causes disabling error or deadlock. + List> curEnabledArray = new ArrayList>(); + List> nextEnabledArray = new ArrayList>(); + + //LinkedList[] curEnabledArray = new LinkedList[arraySize]; + //LinkedList[] nextEnabledArray = new LinkedList[arraySize]; + for (int i = 0; i < arraySize; i++) { + StateGraph lpn_tmp = lpnList[i]; + LinkedList enabledList = lpn_tmp.getEnabled(curStateArray[i]); + //curEnabledArray[i] = enabledList; + curEnabledArray.add(i, enabledList); + enabledList = lpn_tmp.getEnabled(nextStateArray[i]); + //nextEnabledArray[i] = enabledList; + nextEnabledArray.add(i, enabledList); + + Transition disabledTran = firedTran.disablingError(curEnabledArray.get(i),nextEnabledArray.get(i)); + + if (disabledTran != null) { + System.err.println("Disabling Error: " + + disabledTran.getFullLabel() + " is disabled by " + + firedTran.getFullLabel()); + failure = true; + break main_while_loop; + } + } + + if (Analysis.deadLock(lpnList, nextStateArray) == true) { + //System.out.println("*** Verification failed: deadlock."); + failure = true; + break main_while_loop; + } + + /* + * Check if the local indices of nextStateArray already exist. + * if not, add it into reachable set, and push it onto stack. + */ + localIdxArray = Analysis.getLocalStateIdxArray(lpnList, nextStateArray, true); + + Boolean existingState = false; + if (reachAll != null && Mdd.contains(reachAll, localIdxArray) == true) + existingState = true; + else if (Mdd.contains(reach, localIdxArray) == true) + existingState = true; + + if (existingState == false) { + mddMgr.add(reach, localIdxArray, compressed); + //newStateCnt++; + stateStack.push(nextStateArray); + lpnTranStack.push((LpnTranList) nextEnabledArray.get(0).clone()); + curIndexStack.push(0); + totalStates++; + } + } + + double totalStateCnt = Mdd.numberOfStates(reach); + + System.out.println("---> run statistics: \n" + + "# LPN transition firings: " + tranFiringCnt + "\n" + + "# of prjStates found: " + totalStateCnt + "\n" + + "max_stack_depth: " + max_stack_depth + "\n" + + "peak MDD nodes: " + peakMddNodeCnt + "\n" + + "peak used memory: " + peakUsedMem / 1000000 + " MB\n" + + "peak total memory: " + peakTotalMem / 1000000 + " MB\n"); + + return null; + } + + /** + * findsg using iterative approach based on DFS search. The states found are + * stored in MDD. + * + * It is similar to findsg_dfs_mdd_1 except that when a state is considered + * during DFS, all enabled transition are fired, and all its successor + * states are found in an iteration. + * + * @param lpnList + * @param curLocalStateArray + * @param enabledArray + * @return a linked list of a sequence of LPN transitions leading to the + * failure if it is not empty. + */ + public Stack search_dfs_mdd_2(final StateGraph[] lpnList, final State[] initStateArray) { + System.out.println("---> calling function search_dfs_mdd_2"); + + int tranFiringCnt = 0; + int totalStates = 0; + int arraySize = lpnList.length; + long peakUsedMem = 0; + long peakTotalMem = 0; + long peakMddNodeCnt = 0; + int memUpBound = 1000; // Set an upper bound of memory in MB usage to + // trigger MDD compression. + boolean failure = false; + + MDT state2Explore = new MDT(arraySize); + state2Explore.push(initStateArray); + totalStates++; + long peakState2Explore = 0; + + Stack searchDepth = new Stack(); + searchDepth.push(1); + + boolean compressed = false; + mddNode reachAll = null; + mddNode reach = Mdd.newNode(); + + main_while_loop: + while (failure == false && state2Explore.empty() == false) { + long curTotalMem = Runtime.getRuntime().totalMemory(); + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + + if (curTotalMem > peakTotalMem) + peakTotalMem = curTotalMem; + + if (curUsedMem > peakUsedMem) + peakUsedMem = curUsedMem; + + iterations++; + if (iterations % 100000 == 0) { + int mddNodeCnt = mddMgr.nodeCnt(); + peakMddNodeCnt = peakMddNodeCnt > mddNodeCnt ? peakMddNodeCnt : mddNodeCnt; + int state2ExploreSize = state2Explore.size(); + peakState2Explore = peakState2Explore > state2ExploreSize ? peakState2Explore : state2ExploreSize; + + System.out.println("---> #iteration " + iterations + + "> # LPN transition firings: " + tranFiringCnt + + ", # of prjStates found: " + totalStates + + ", # states to explore: " + state2ExploreSize + + ", # MDT nodes: " + state2Explore.nodeCnt() + + ", total MDD nodes: " + mddNodeCnt + + " used memory: " + (float) curUsedMem / 1000000 + + " free memory: " + + (float) Runtime.getRuntime().freeMemory() / 1000000); + + if (curUsedMem >= memUpBound * 1000000) { + mddMgr.compress(reach); + if (reachAll == null) + reachAll = reach; + else { + mddNode newReachAll = mddMgr.union(reachAll, reach); + if (newReachAll != reachAll) { + mddMgr.remove(reachAll); + reachAll = newReachAll; + } + } + mddMgr.remove(reach); + reach = Mdd.newNode(); + } + } + + State[] curStateArray = state2Explore.pop(); + State[] nextStateArray = null; + + int states2ExploreCurLevel = searchDepth.pop(); + if(states2ExploreCurLevel > 1) + searchDepth.push(states2ExploreCurLevel-1); + + int[] localIdxArray = Analysis.getLocalStateIdxArray(lpnList, curStateArray, false); + mddMgr.add(reach, localIdxArray, compressed); + + int nextStates2Explore = 0; + for (int index = arraySize - 1; index >= 0; index--) { + StateGraph curLpn = lpnList[index]; + State curState = curStateArray[index]; + LinkedList curEnabledSet = curLpn.getEnabled(curState); + + LpnTranList curEnabled = (LpnTranList) curEnabledSet.clone(); + while (curEnabled.size() > 0) { + Transition firedTran = curEnabled.removeLast(); + // TODO: (check) Not sure if curLpn.fire is correct. + nextStateArray = curLpn.fire(lpnList, curStateArray, firedTran); + tranFiringCnt++; + + for (int i = 0; i < arraySize; i++) { + StateGraph lpn_tmp = lpnList[i]; + if (curStateArray[i] == nextStateArray[i]) + continue; + + LinkedList curEnabled_l = lpn_tmp.getEnabled(curStateArray[i]); + LinkedList nextEnabled = lpn_tmp.getEnabled(nextStateArray[i]); + Transition disabledTran = firedTran.disablingError(curEnabled_l, nextEnabled); + if (disabledTran != null) { + System.err.println("Verification failed: disabling error: " + + disabledTran.getFullLabel() + + " disabled by " + + firedTran.getFullLabel() + "!!!"); + failure = true; + break main_while_loop; + } + } + + if (Analysis.deadLock(lpnList, nextStateArray) == true) { + System.err.println("Verification failed: deadlock."); + failure = true; + break main_while_loop; + } + + /* + * Check if the local indices of nextStateArray already exist. + */ + localIdxArray = Analysis.getLocalStateIdxArray(lpnList, nextStateArray, false); + + Boolean existingState = false; + if (reachAll != null && Mdd.contains(reachAll, localIdxArray) == true) + existingState = true; + else if (Mdd.contains(reach, localIdxArray) == true) + existingState = true; + else if(state2Explore.contains(nextStateArray)==true) + existingState = true; + + if (existingState == false) { + totalStates++; + //mddMgr.add(reach, localIdxArray, compressed); + state2Explore.push(nextStateArray); + nextStates2Explore++; + } + } + } + if(nextStates2Explore > 0) + searchDepth.push(nextStates2Explore); + } + + System.out.println("-------------------------------------\n" + + "---> run statistics: \n" + + " # Depth of search (Length of Cex): " + searchDepth.size() + "\n" + + " # LPN transition firings: " + (double)tranFiringCnt/1000000 + " M\n" + + " # of prjStates found: " + (double)totalStates / 1000000 + " M\n" + + " peak states to explore : " + (double) peakState2Explore / 1000000 + " M\n" + + " peak MDD nodes: " + peakMddNodeCnt + "\n" + + " peak used memory: " + peakUsedMem / 1000000 + " MB\n" + + " peak total memory: " + peakTotalMem /1000000 + " MB\n" + + "_____________________________________"); + + return null; + } + + + public LinkedList search_bfs(final StateGraph[] sgList, final State[] initStateArray) { + System.out.println("---> starting search_bfs"); + + long peakUsedMem = 0; + long peakTotalMem = 0; + long peakMddNodeCnt = 0; + int memUpBound = 1000; // Set an upper bound of memory in MB usage to + // trigger MDD compression. + + int arraySize = sgList.length; + + for (int i = 0; i < arraySize; i++) + sgList[i].addState(initStateArray[i]); + + mddNode reachSet = null; + mddNode reach = Mdd.newNode(); + MDT frontier = new MDT(arraySize); + MDT image = new MDT(arraySize); + + frontier.push(initStateArray); + + State[] curStateArray = null; + int tranFiringCnt = 0; + int totalStates = 0; + int imageSize = 0; + + boolean verifyError = false; + + bfsWhileLoop: while (true) { + if (verifyError == true) + break; + + long curTotalMem = Runtime.getRuntime().totalMemory(); + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + + if (curTotalMem > peakTotalMem) + peakTotalMem = curTotalMem; + + if (curUsedMem > peakUsedMem) + peakUsedMem = curUsedMem; + + long curMddNodeCnt = mddMgr.nodeCnt(); + peakMddNodeCnt = peakMddNodeCnt > curMddNodeCnt ? peakMddNodeCnt : curMddNodeCnt; + + iterations++; + System.out.println("iteration " + iterations + + "> # LPN transition firings: " + tranFiringCnt + + ", # of prjStates found: " + totalStates + + ", total MDD nodes: " + curMddNodeCnt + + " used memory: " + (float) curUsedMem / 1000000 + + " free memory: " + + (float) Runtime.getRuntime().freeMemory() / 1000000); + + if (curUsedMem >= memUpBound * 1000000) { + mddMgr.compress(reach); + if (reachSet == null) + reachSet = reach; + else { + mddNode newReachSet = mddMgr.union(reachSet, reach); + if (newReachSet != reachSet) { + mddMgr.remove(reachSet); + reachSet = newReachSet; + } + } + mddMgr.remove(reach); + reach = Mdd.newNode(); + } + + while(frontier.empty() == false) { + boolean deadlock = true; + +// Stack curStateArrayList = frontier.pop(); +// while(curStateArrayList.empty() == false) { +// curStateArray = curStateArrayList.pop(); + { + curStateArray = frontier.pop(); + int[] localIdxArray = Analysis.getLocalStateIdxArray(sgList, curStateArray, false); + mddMgr.add(reach, localIdxArray, false); + totalStates++; + + for (int i = 0; i < arraySize; i++) { + LinkedList curEnabled = sgList[i].getEnabled(curStateArray[i]); + if (curEnabled.size() > 0) + deadlock = false; + + for (Transition firedTran : curEnabled) { + // TODO: (check) Not sure if sgList[i].fire is correct. + State[] nextStateArray = sgList[i].fire(sgList, curStateArray, firedTran); + tranFiringCnt++; + + /* + * Check if any transitions can be disabled by fireTran. + */ + LinkedList nextEnabled = sgList[i].getEnabled(nextStateArray[i]); + Transition disabledTran = firedTran.disablingError(curEnabled, nextEnabled); + if (disabledTran != null) { + System.err.println("*** Verification failed: disabling error: " + + disabledTran.getFullLabel() + + " disabled by " + + firedTran.getFullLabel() + "!!!"); + verifyError = true; + break bfsWhileLoop; + } + + localIdxArray = Analysis.getLocalStateIdxArray(sgList, nextStateArray, false); + if (Mdd.contains(reachSet, localIdxArray) == false && Mdd.contains(reach, localIdxArray) == false && frontier.contains(nextStateArray) == false) { + if(image.contains(nextStateArray)==false) { + image.push(nextStateArray); + imageSize++; + } + } + } + } + } + + + + /* + * If curStateArray deadlocks (no enabled transitions), terminate. + */ + if (deadlock == true) { + System.err.println("*** Verification failed: deadlock."); + verifyError = true; + break bfsWhileLoop; + } + } + + if(image.empty()==true) break; + + System.out.println("---> size of image: " + imageSize); + + frontier = image; + image = new MDT(arraySize); + imageSize = 0; + } + + System.out.println("---> final numbers: # LPN transition firings: " + tranFiringCnt / 1000000 + "M\n" + + "---> # of prjStates found: " + (double) totalStates / 1000000 + "M\n" + + "---> peak total memory: " + peakTotalMem / 1000000F + " MB\n" + + "---> peak used memory: " + peakUsedMem / 1000000F + " MB\n" + + "---> peak MDD nodes: " + peakMddNodeCnt); + + return null; + } + + /** + * BFS findsg using iterative approach. THe states found are stored in MDD. + * + * @param lpnList + * @param curLocalStateArray + * @param enabledArray + * @return a linked list of a sequence of LPN transitions leading to the + * failure if it is not empty. + */ + public LinkedList search_bfs_mdd_localFirings(final StateGraph[] lpnList, final State[] initStateArray) { + System.out.println("---> starting search_bfs"); + + long peakUsedMem = 0; + long peakTotalMem = 0; + + int arraySize = lpnList.length; + + for (int i = 0; i < arraySize; i++) + lpnList[i].addState(initStateArray[i]); + + // mddNode reachSet = mddMgr.newNode(); + // mddMgr.add(reachSet, curLocalStateArray); + mddNode reachSet = null; + mddNode exploredSet = null; + List> nextSetArray = new ArrayList>(); + //LinkedList[] nextSetArray = new LinkedList[arraySize]; + for (int i = 0; i < arraySize; i++) + nextSetArray.add(i,new LinkedList()); + + mddNode initMdd = mddMgr.doLocalFirings(lpnList, initStateArray, null); + mddNode curMdd = initMdd; + reachSet = curMdd; + mddNode nextMdd = null; + + int[] curStateArray = null; + int tranFiringCnt = 0; + + boolean verifyError = false; + + bfsWhileLoop: while (true) { + if (verifyError == true) + break; + + long curTotalMem = Runtime.getRuntime().totalMemory(); + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + + if (curTotalMem > peakTotalMem) + peakTotalMem = curTotalMem; + + if (curUsedMem > peakUsedMem) + peakUsedMem = curUsedMem; + + curStateArray = mddMgr.next(curMdd, curStateArray); + + if (curStateArray == null) { + // Break the loop if no new next states are found. + // System.out.println("nextSet size " + nextSet.size()); + if (nextMdd == null) + break bfsWhileLoop; + + if (exploredSet == null) + exploredSet = curMdd; + else { + mddNode newExplored = mddMgr.union(exploredSet, curMdd); + if (newExplored != exploredSet) + mddMgr.remove(exploredSet); + exploredSet = newExplored; + } + + mddMgr.remove(curMdd); + curMdd = nextMdd; + nextMdd = null; + + iterations++; + System.out.println("iteration " + iterations + + "> # LPN transition firings: " + tranFiringCnt + + ", # of union calls: " + mddNode.numCalls + + ", # of union cache nodes: " + mddNode.cacheNodes + + ", total MDD nodes: " + mddMgr.nodeCnt() + + " used memory: " + (float) curUsedMem / 1000000 + + " free memory: " + + (float) Runtime.getRuntime().freeMemory() / 1000000); + System.out.println("---> # of prjStates found: " + Mdd.numberOfStates(reachSet) + + ", CurSet.Size = " + Mdd.numberOfStates(curMdd)); + continue; + } + + if (exploredSet != null && Mdd.contains(exploredSet, curStateArray) == true) + continue; + + // If curStateArray deadlocks (no enabled transitions), terminate. + if (Analysis.deadLock(lpnList, curStateArray) == true) { + System.err.println("*** Verification failed: deadlock."); + verifyError = true; + break bfsWhileLoop; + } + + // Do firings of non-local LPN transitions. + for (int index = arraySize - 1; index >= 0; index--) { + StateGraph curLpn = lpnList[index]; + LinkedList curLocalEnabled = curLpn.getEnabled(curStateArray[index]); + + if (curLocalEnabled.size() == 0 || curLocalEnabled.getFirst().isLocal() == true) + continue; + + for (Transition firedTran : curLocalEnabled) { + + if (firedTran.isLocal() == true) + continue; + // TODO: (check) Not sure if curLpn.fire is correct. + State[] nextStateArray = curLpn.fire(lpnList, curStateArray, firedTran); + tranFiringCnt++; + + @SuppressWarnings("unused") + ArrayList> nextEnabledArray = new ArrayList>(1); + for (int i = 0; i < arraySize; i++) { + if (curStateArray[i] == nextStateArray[i].getIndex()) + continue; + + StateGraph lpn_tmp = lpnList[i]; + LinkedList curEnabledList = lpn_tmp.getEnabled(curStateArray[i]); + LinkedList nextEnabledList = lpn_tmp.getEnabled(nextStateArray[i].getIndex()); + + Transition disabledTran = firedTran.disablingError(curEnabledList, nextEnabledList); + if (disabledTran != null) { + System.err.println("Verification failed: disabling error: " + + disabledTran.getFullLabel() + + ": is disabled by " + + firedTran.getFullLabel() + "!!!"); + verifyError = true; + break bfsWhileLoop; + } + } + + if (Analysis.deadLock(lpnList, nextStateArray) == true) { + //System.err.println("*** Verification failed: deadlock."); + verifyError = true; + break bfsWhileLoop; + } + + // Add nextPrjState into prjStateSet + // If nextPrjState has been traversed before, skip to the + // next + // enabled transition. + int[] nextIdxArray = Analysis.getIdxArray(nextStateArray); + if (reachSet != null && Mdd.contains(reachSet, nextIdxArray) == true) + continue; + + mddNode newNextMdd = mddMgr.doLocalFirings(lpnList, nextStateArray, reachSet); + + mddNode newReachSet = mddMgr.union(reachSet, newNextMdd); + if (newReachSet != reachSet) + mddMgr.remove(reachSet); + reachSet = newReachSet; + + if (nextMdd == null) + nextMdd = newNextMdd; + else { + mddNode tmpNextMdd = mddMgr.union(nextMdd, newNextMdd); + if (tmpNextMdd != nextMdd) + mddMgr.remove(nextMdd); + nextMdd = tmpNextMdd; + mddMgr.remove(newNextMdd); + } + } + } + } + + System.out.println("---> final numbers: # LPN transition firings: " + + tranFiringCnt + "\n" + "---> # of prjStates found: " + + (Mdd.numberOfStates(reachSet)) + "\n" + + "---> peak total memory: " + peakTotalMem / 1000000F + + " MB\n" + "---> peak used memory: " + peakUsedMem / 1000000F + + " MB\n" + "---> peak MMD nodes: " + mddMgr.peakNodeCnt()); + + return null; + } + + + /** + * partial order reduction (Original version of Hao's POR with behavioral analysis) + * This method is not used anywhere. See searchPOR_behavioral for POR with behavioral analysis. + * + * @param lpnList + * @param curLocalStateArray + * @param enabledArray + */ + public Stack search_dfs_por(final StateGraph[] lpnList, final State[] initStateArray, LPNTranRelation lpnTranRelation, String approach) { + System.out.println("---> Calling search_dfs with partial order reduction"); + + long peakUsedMem = 0; + long peakTotalMem = 0; + double stateCount = 1; + int max_stack_depth = 0; + int iterations = 0; + boolean useMdd = true; + mddNode reach = Mdd.newNode(); + + //init por + edu.utah.ece.async.lema.verification.platu.por1.AmpleSet ampleClass = new edu.utah.ece.async.lema.verification.platu.por1.AmpleSet(); + //AmpleSubset ampleClass = new AmpleSubset(); + HashMap> indepTranSet = new HashMap>(); + + if(approach == "state") + indepTranSet = ampleClass.getIndepTranSet_FromState(lpnList, lpnTranRelation); + else if (approach == "lpn") + indepTranSet = ampleClass.getIndepTranSet_FromLPN(lpnList); + + System.out.println("finish get independent set!!!!"); + + boolean failure = false; + int tranFiringCnt = 0; + int arraySize = lpnList.length; + + HashSet stateStack = new HashSet(); + Stack lpnTranStack = new Stack(); + Stack> firedTranStack = new Stack>(); + + //get initial enable transition set + @SuppressWarnings("unchecked") + LinkedList[] initEnabledArray = new LinkedList[arraySize]; + for (int i = 0; i < arraySize; i++) { + lpnList[i].getLpn().setLpnIndex(i); + initEnabledArray[i] = lpnList[i].getEnabled(initStateArray[i]); + } + + + //set initEnableSubset + //LPNTranSet initEnableSubset = ampleClass.generateAmpleList(false, approach,initEnabledArray, indepTranSet); + LpnTranList initEnableSubset = ampleClass.generateAmpleTranSet(initEnabledArray, indepTranSet); + /* + * Initialize the reach state set with the initial state. + */ + HashSet prjStateSet = new HashSet(); + PrjState initPrjState = new PrjState(initStateArray); + + if (useMdd) { + int[] initIdxArray = Analysis.getIdxArray(initStateArray); + mddMgr.add(reach, initIdxArray, true); + } + else + prjStateSet.add(initPrjState); + + stateStack.add(initPrjState); + PrjState stateStackTop = initPrjState; + lpnTranStack.push(initEnableSubset); + firedTranStack.push(new HashSet()); + + /* + * Start the main search loop. + */ + main_while_loop: + while(failure == false && stateStack.size() != 0) { + long curTotalMem = Runtime.getRuntime().totalMemory(); + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + + if (curTotalMem > peakTotalMem) + peakTotalMem = curTotalMem; + + if (curUsedMem > peakUsedMem) + peakUsedMem = curUsedMem; + + if (stateStack.size() > max_stack_depth) + max_stack_depth = stateStack.size(); + + iterations++; + if (iterations % 500000 == 0) { + if (useMdd==true) + stateCount = Mdd.numberOfStates(reach); + else + stateCount = prjStateSet.size(); + + System.out.println("---> #iteration " + iterations + + "> # LPN transition firings: " + tranFiringCnt + + ", # of prjStates found: " + stateCount + + ", max_stack_depth: " + max_stack_depth + + ", total MDD nodes: " + mddMgr.nodeCnt() + + " used memory: " + (float) curUsedMem / 1000000 + + " free memory: " + + (float) Runtime.getRuntime().freeMemory() / 1000000); + } + + State[] curStateArray = stateStackTop.toStateArray(); + LpnTranList curEnabled = lpnTranStack.peek(); + +// for (LPNTran tran : curEnabled) +// for (int i = 0; i < arraySize; i++) +// if (lpnList[i] == tran.getLpn()) +// if (tran.isEnabled(curStateArray[i]) == false) { +// System.out.println("transition " + tran.getFullLabel() + " not enabled in the current state"); +// System.exit(0); +// } + + // If all enabled transitions of the current LPN are considered, then consider the next LPN + // by increasing the curIndex. + // Otherwise, if all enabled transitions of all LPNs are considered, then pop the stacks. + if(curEnabled.size() == 0) { + lpnTranStack.pop(); + firedTranStack.pop(); + stateStack.remove(stateStackTop); + stateStackTop = stateStackTop.getFather(); + if (stateStack.size() > 0) + traceCex.removeLast(); + continue; + } + + Transition firedTran = curEnabled.removeFirst(); + firedTranStack.peek().add(firedTran); + traceCex.addLast(firedTran); + + //System.out.println(tranFiringCnt + ": firedTran: "+ firedTran.getFullLabel()); + // TODO: (??) Not sure if the state graph sg below is correct. + StateGraph sg = null; + for (int i=0; i[] curEnabledArray = new LinkedList[arraySize]; + @SuppressWarnings("unchecked") + LinkedList[] nextEnabledArray = new LinkedList[arraySize]; + for (int i = 0; i < arraySize; i++) { + lpnList[i].getLpn().setLpnIndex(i); + StateGraph lpn_tmp = lpnList[i]; + LinkedList enabledList = lpn_tmp.getEnabled(curStateArray[i]); + curEnabledArray[i] = enabledList; + enabledList = lpn_tmp.getEnabled(nextStateArray[i]); + nextEnabledArray[i] = enabledList; + + Transition disabledTran = firedTran.disablingError(curEnabledArray[i], nextEnabledArray[i]); + if(disabledTran != null) { + System.out.println("---> Disabling Error: " + disabledTran.getFullLabel() + " is disabled by " + firedTran.getFullLabel()); + + System.out.println("Current state:"); + for(int ii = 0; ii < arraySize; ii++) { + System.out.println("module " + lpnList[ii].getLpn().getLabel()); + System.out.println(curStateArray[ii]); + System.out.println("Enabled set: " + curEnabledArray[ii]); + } + + System.out.println("======================\nNext state:"); + for(int ii = 0; ii < arraySize; ii++) { + System.out.println("module " + lpnList[ii].getLpn().getLabel()); + System.out.println(nextStateArray[ii]); + System.out.println("Enabled set: " + nextEnabledArray[ii]); + } + System.out.println(); + + failure = true; + break main_while_loop; + } + } + + if (Analysis.deadLock(lpnList, nextStateArray) == true) { + System.out.println("---> Deadlock."); +// System.out.println("Deadlock state:"); +// for(int ii = 0; ii < arraySize; ii++) { +// System.out.println("module " + lpnList[ii].getLabel()); +// System.out.println(nextStateArray[ii]); +// System.out.println("Enabled set: " + nextEnabledArray[ii]); +// } + + failure = true; + break main_while_loop; + } + + /* + // Add nextPrjState into prjStateSet + // If nextPrjState has been traversed before, skip to the next + // enabled transition. + //exist cycle + */ + + PrjState nextPrjState = new PrjState(nextStateArray); + boolean isExisting = false; + int[] nextIdxArray = null; + if(useMdd==true) + nextIdxArray = Analysis.getIdxArray(nextStateArray); + + if (useMdd == true) + isExisting = Mdd.contains(reach, nextIdxArray); + else + isExisting = prjStateSet.contains(nextPrjState); + + if (isExisting == false) { + if (useMdd == true) { + + mddMgr.add(reach, nextIdxArray, true); + } + else + prjStateSet.add(nextPrjState); + + //get next enable transition set + //LPNTranSet nextEnableSubset = ampleClass.generateAmpleList(false, approach, nextEnabledArray, indepTranSet); + LpnTranList nextEnableSubset = ampleClass.generateAmpleTranSet(nextEnabledArray, indepTranSet); + +// LPNTranSet nextEnableSubset = new LPNTranSet(); +// for (int i = 0; i < arraySize; i++) +// for (LPNTran tran : nextEnabledArray[i]) +// nextEnableSubset.addLast(tran); + + stateStack.add(nextPrjState); + stateStackTop.setChild(nextPrjState); + nextPrjState.setFather(stateStackTop); + stateStackTop = nextPrjState; + lpnTranStack.push(nextEnableSubset); + firedTranStack.push(new HashSet()); + + +// for (int i = 0; i < arraySize; i++) +// for (LPNTran tran : nextEnabledArray[i]) +// System.out.print(tran.getFullLabel() + ", "); +// System.out.println("\n"); +// +// for (LPNTran tran : nextEnableSubset) +// System.out.print(tran.getFullLabel() + ", "); +// System.out.println("\n-----------------------------------------------------\n"); + +// HashSet allEnabledSet = new HashSet(); +// for (int i = 0; i < arraySize; i++) { +// for (LPNTran tran : nextEnabledArray[i]) { +// allEnabledSet.add(tran); +// System.out.print(tran.getFullLabel() + ", "); +// } +// } +// +// System.out.println("\n"); +// +// if(nextEnableSubset.size() > 0) { +// for (LPNTran tran : nextEnableSubset) { +// if (allEnabledSet.contains(tran) == false) { +// System.out.println("\n\n" + tran.getFullLabel() + " in reduced set but not enabled\n"); +// System.exit(0); +// } +// System.out.print(tran.getFullLabel() + ", "); +// } +// +// System.out.println("\n # of states : " + prjStateSet.size() + "\n-----------------------------------------------------\n"); +// } + continue; + } + + /* + * Remove firedTran from traceCex if its successor state already exists. + */ + traceCex.removeLast(); + + /* + * When firedTran forms a cycle in the state graph, consider all enabled transitions except those + * 1. already fired in the current state, + * 2. in the ample set of the next state. + */ + if(stateStack.contains(nextPrjState)==true && curEnabled.size()==0) { + //System.out.println("formed a cycle......"); + + LpnTranList original = new LpnTranList(); + LpnTranList reduced = new LpnTranList(); + + //LPNTranSet nextStateAmpleSet = ampleClass.generateAmpleList(false, approach, nextEnabledArray, indepTranSet); + LpnTranList nextStateAmpleSet = ampleClass.generateAmpleTranSet(nextEnabledArray, indepTranSet); + +// System.out.println("Back state's ample set:"); +// for(LPNTran tran : nextStateAmpleSet) +// System.out.print(tran.getFullLabel() + ", "); +// System.out.println("\n"); + + int enabledTranCnt = 0; + LpnTranList[] tmp = new LpnTranList[arraySize]; + for (int i = 0; i < arraySize; i++) { + tmp[i] = new LpnTranList(); + for (Transition tran : curEnabledArray[i]) { + original.addLast(tran); + if (firedTranStack.peek().contains(tran)==false && nextStateAmpleSet.contains(tran)==false) { + tmp[i].addLast(tran); + reduced.addLast(tran); + enabledTranCnt++; + } + } + } + + + LpnTranList ampleSet = new LpnTranList(); + if(enabledTranCnt > 0) + //ampleSet = ampleClass.generateAmpleList(false, approach, tmp, indepTranSet); + ampleSet = ampleClass.generateAmpleTranSet(tmp, indepTranSet); + + LpnTranList sortedAmpleSet = ampleSet; + + /* + * Sort transitions in ampleSet for better performance for MDD. + * Not needed for hash table. + */ + if (useMdd == true) { + LpnTranList[] newCurEnabledArray = new LpnTranList[arraySize]; + for (int i = 0; i < arraySize; i++) + newCurEnabledArray[i] = new LpnTranList(); + + for (Transition tran : ampleSet) + newCurEnabledArray[tran.getLpn().getLpnIndex()].addLast(tran); + + sortedAmpleSet = new LpnTranList(); + for (int i = 0; i < arraySize; i++) { + LpnTranList localEnabledSet = newCurEnabledArray[i]; + for (Transition tran : localEnabledSet) + sortedAmpleSet.addLast(tran); + } + } + + +// for(LPNTran tran : original) +// System.out.print(tran.getFullLabel() + ", "); +// System.out.println("\n"); +// +// for(LPNTran tran : ampleSet) +// System.out.print(tran.getFullLabel() + ", "); +// System.out.println("\n"); +// System.out.println("\n ---------111111-------------\n"); + + +// for(LPNTran tran : firedTranStack.peek()) +// allCurEnabled.remove(tran); +// + lpnTranStack.pop(); + lpnTranStack.push(sortedAmpleSet); + +// for (int i = 0; i < arraySize; i++) { +// for (LPNTran tran : curEnabledArray[i]) { +// System.out.print(tran.getFullLabel() + ", "); +// } +// } +// System.out.println("\n"); +// +// for(LPNTran tran : allCurEnabled) +// System.out.print(tran.getFullLabel() + ", "); +// System.out.println("\n-------------------------\n"); + } + + //System.out.println("Backtrack........\n"); + }//END while (stateStack.empty() == false) + + + if (useMdd==true) + stateCount = Mdd.numberOfStates(reach); + else + stateCount = prjStateSet.size(); + + //long curTotalMem = Runtime.getRuntime().totalMemory(); + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + System.out.println("SUMMARY: # LPN transition firings: " + tranFiringCnt + + ", # of prjStates found: " + stateCount + + ", max_stack_depth: " + max_stack_depth + + ", used memory: " + (float) curUsedMem / 1000000 + + ", free memory: " + + (float) Runtime.getRuntime().freeMemory() / 1000000); + + return null; + } + + /** + * partial order reduction with behavioral analysis. (Adapted from search_dfs_por.) + * + * @param sgList + * @param curLocalStateArray + * @param enabledArray + */ + public StateGraph[] searchPOR_behavioral(final StateGraph[] sgList, final State[] initStateArray, LPNTranRelation lpnTranRelation, String approach) { + System.out.println("---> calling function searchPOR_behavioral"); + System.out.println("---> " + Options.getPOR()); + //System.out.println("---> " + Options.getCycleClosingMthd()); + //System.out.println("---> " + Options.getCycleClosingAmpleMethd()); + + long peakUsedMem = 0; + long peakTotalMem = 0; + double stateCount = 1; + int max_stack_depth = 0; + int iterations = 0; + //boolean useMdd = true; + boolean useMdd = false; + mddNode reach = Mdd.newNode(); + + //init por + AmpleSet ampleClass = new AmpleSet(); + //AmpleSubset ampleClass = new AmpleSubset(); + HashMap> indepTranSet = new HashMap>(); + + if(approach == "state") + indepTranSet = ampleClass.getIndepTranSet_FromState(sgList, lpnTranRelation); + else if (approach == "lpn") + indepTranSet = ampleClass.getIndepTranSet_FromLPN(sgList); + + System.out.println("finish get independent set!!!!"); + + boolean failure = false; + int tranFiringCnt = 0; + int arraySize = sgList.length; + + HashSet stateStack = new HashSet(); + Stack lpnTranStack = new Stack(); + Stack> firedTranStack = new Stack>(); + + //get initial enable transition set + @SuppressWarnings("unchecked") + LinkedList[] initEnabledArray = new LinkedList[arraySize]; + for (int i = 0; i < arraySize; i++) { + sgList[i].getLpn().setLpnIndex(i); + initEnabledArray[i] = sgList[i].getEnabled(initStateArray[i]); + } + + //set initEnableSubset + //LPNTranSet initEnableSubset = ampleClass.generateAmpleList(false, approach,initEnabledArray, indepTranSet); + LpnTranList initEnableSubset = ampleClass.generateAmpleTranSet(initEnabledArray, indepTranSet); + /* + * Initialize the reach state set with the initial state. + */ + HashSet prjStateSet = new HashSet(); + PrjState initPrjState = new PrjState(initStateArray); + + if (useMdd) { + int[] initIdxArray = Analysis.getIdxArray(initStateArray); + mddMgr.add(reach, initIdxArray, true); + } + else + prjStateSet.add(initPrjState); + + stateStack.add(initPrjState); + PrjState stateStackTop = initPrjState; + lpnTranStack.push(initEnableSubset); + firedTranStack.push(new HashSet()); + + /* + * Start the main search loop. + */ + main_while_loop: + while(failure == false && stateStack.size() != 0) { + long curTotalMem = Runtime.getRuntime().totalMemory(); + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + + if (curTotalMem > peakTotalMem) + peakTotalMem = curTotalMem; + + if (curUsedMem > peakUsedMem) + peakUsedMem = curUsedMem; + + if (stateStack.size() > max_stack_depth) + max_stack_depth = stateStack.size(); + + iterations++; + if (iterations % 500000 == 0) { + if (useMdd==true) + stateCount = Mdd.numberOfStates(reach); + else + stateCount = prjStateSet.size(); + + System.out.println("---> #iteration " + iterations + + "> # LPN transition firings: " + tranFiringCnt + + ", # of prjStates found: " + stateCount + + ", max_stack_depth: " + max_stack_depth + + ", total MDD nodes: " + mddMgr.nodeCnt() + + " used memory: " + (float) curUsedMem / 1000000 + + " free memory: " + + (float) Runtime.getRuntime().freeMemory() / 1000000); + } + + State[] curStateArray = stateStackTop.toStateArray(); + LpnTranList curEnabled = lpnTranStack.peek(); + +// for (LPNTran tran : curEnabled) +// for (int i = 0; i < arraySize; i++) +// if (lpnList[i] == tran.getLpn()) +// if (tran.isEnabled(curStateArray[i]) == false) { +// System.out.println("transition " + tran.getFullLabel() + " not enabled in the current state"); +// System.exit(0); +// } + + // If all enabled transitions of the current LPN are considered, then consider the next LPN + // by increasing the curIndex. + // Otherwise, if all enabled transitions of all LPNs are considered, then pop the stacks. + if(curEnabled.size() == 0) { + lpnTranStack.pop(); + firedTranStack.pop(); + stateStack.remove(stateStackTop); + stateStackTop = stateStackTop.getFather(); + if (stateStack.size() > 0) + traceCex.removeLast(); + continue; + } + + Transition firedTran = curEnabled.removeFirst(); + firedTranStack.peek().add(firedTran); + traceCex.addLast(firedTran); + + StateGraph sg = null; + for (int i=0; i[] curEnabledArray = new LinkedList[arraySize]; + @SuppressWarnings("unchecked") + LinkedList[] nextEnabledArray = new LinkedList[arraySize]; + for (int i = 0; i < arraySize; i++) { + sgList[i].getLpn().setLpnIndex(i); + StateGraph lpn_tmp = sgList[i]; + LinkedList enabledList = lpn_tmp.getEnabled(curStateArray[i]); + curEnabledArray[i] = enabledList; + enabledList = lpn_tmp.getEnabled(nextStateArray[i]); + nextEnabledArray[i] = enabledList; + + Transition disabledTran = firedTran.disablingError(curEnabledArray[i], nextEnabledArray[i]); + if(disabledTran != null) { + System.out.println("---> Disabling Error: " + disabledTran.getFullLabel() + " is disabled by " + firedTran.getFullLabel()); + + System.out.println("Current state:"); + for(int ii = 0; ii < arraySize; ii++) { + System.out.println("module " + sgList[ii].getLpn().getLabel()); + System.out.println(curStateArray[ii]); + System.out.println("Enabled set: " + curEnabledArray[ii]); + } + + System.out.println("======================\nNext state:"); + for(int ii = 0; ii < arraySize; ii++) { + System.out.println("module " + sgList[ii].getLpn().getLabel()); + System.out.println(nextStateArray[ii]); + System.out.println("Enabled set: " + nextEnabledArray[ii]); + } + System.out.println(); + + failure = true; + break main_while_loop; + } + } + + if (Analysis.deadLock(sgList, nextStateArray) == true) { + System.out.println("---> Deadlock."); +// System.out.println("Deadlock state:"); +// for(int ii = 0; ii < arraySize; ii++) { +// System.out.println("module " + lpnList[ii].getLabel()); +// System.out.println(nextStateArray[ii]); +// System.out.println("Enabled set: " + nextEnabledArray[ii]); +// } + + failure = true; + break main_while_loop; + } + + /* + // Add nextPrjState into prjStateSet + // If nextPrjState has been traversed before, skip to the next + // enabled transition. + //exist cycle + */ + + PrjState nextPrjState = new PrjState(nextStateArray); + boolean isExisting = false; + int[] nextIdxArray = null; + if(useMdd==true) + nextIdxArray = Analysis.getIdxArray(nextStateArray); + + if (useMdd == true) + isExisting = Mdd.contains(reach, nextIdxArray); + else + isExisting = prjStateSet.contains(nextPrjState); + + if (isExisting == false) { + if (useMdd == true) { + + mddMgr.add(reach, nextIdxArray, true); + } + else + prjStateSet.add(nextPrjState); + + //get next enable transition set + //LPNTranSet nextEnableSubset = ampleClass.generateAmpleList(false, approach, nextEnabledArray, indepTranSet); + LpnTranList nextEnableSubset = ampleClass.generateAmpleTranSet(nextEnabledArray, indepTranSet); + +// LPNTranSet nextEnableSubset = new LPNTranSet(); +// for (int i = 0; i < arraySize; i++) +// for (LPNTran tran : nextEnabledArray[i]) +// nextEnableSubset.addLast(tran); + + stateStack.add(nextPrjState); + stateStackTop.setChild(nextPrjState); + nextPrjState.setFather(stateStackTop); + stateStackTop = nextPrjState; + lpnTranStack.push(nextEnableSubset); + firedTranStack.push(new HashSet()); + + +// for (int i = 0; i < arraySize; i++) +// for (LPNTran tran : nextEnabledArray[i]) +// System.out.print(tran.getFullLabel() + ", "); +// System.out.println("\n"); +// +// for (LPNTran tran : nextEnableSubset) +// System.out.print(tran.getFullLabel() + ", "); +// System.out.println("\n-----------------------------------------------------\n"); + +// HashSet allEnabledSet = new HashSet(); +// for (int i = 0; i < arraySize; i++) { +// for (LPNTran tran : nextEnabledArray[i]) { +// allEnabledSet.add(tran); +// System.out.print(tran.getFullLabel() + ", "); +// } +// } +// +// System.out.println("\n"); +// +// if(nextEnableSubset.size() > 0) { +// for (LPNTran tran : nextEnableSubset) { +// if (allEnabledSet.contains(tran) == false) { +// System.out.println("\n\n" + tran.getFullLabel() + " in reduced set but not enabled\n"); +// System.exit(0); +// } +// System.out.print(tran.getFullLabel() + ", "); +// } +// +// System.out.println("\n # of states : " + prjStateSet.size() + "\n-----------------------------------------------------\n"); +// } + continue; + } + + /* + * Remove firedTran from traceCex if its successor state already exists. + */ + traceCex.removeLast(); + + /* + * When firedTran forms a cycle in the state graph, consider all enabled transitions except those + * 1. already fired in the current state, + * 2. in the ample set of the next state. + */ + if(stateStack.contains(nextPrjState)==true && curEnabled.size()==0) { + //System.out.println("formed a cycle......"); + + LpnTranList original = new LpnTranList(); + LpnTranList reduced = new LpnTranList(); + + //LPNTranSet nextStateAmpleSet = ampleClass.generateAmpleList(false, approach, nextEnabledArray, indepTranSet); + LpnTranList nextStateAmpleSet = ampleClass.generateAmpleTranSet(nextEnabledArray, indepTranSet); + +// System.out.println("Back state's ample set:"); +// for(LPNTran tran : nextStateAmpleSet) +// System.out.print(tran.getFullLabel() + ", "); +// System.out.println("\n"); + + int enabledTranCnt = 0; + LpnTranList[] tmp = new LpnTranList[arraySize]; + for (int i = 0; i < arraySize; i++) { + tmp[i] = new LpnTranList(); + for (Transition tran : curEnabledArray[i]) { + original.addLast(tran); + if (firedTranStack.peek().contains(tran)==false && nextStateAmpleSet.contains(tran)==false) { + tmp[i].addLast(tran); + reduced.addLast(tran); + enabledTranCnt++; + } + } + } + + + LpnTranList ampleSet = new LpnTranList(); + if(enabledTranCnt > 0) + //ampleSet = ampleClass.generateAmpleList(false, approach, tmp, indepTranSet); + ampleSet = ampleClass.generateAmpleTranSet(tmp, indepTranSet); + + LpnTranList sortedAmpleSet = ampleSet; + + /* + * Sort transitions in ampleSet for better performance for MDD. + * Not needed for hash table. + */ + if (useMdd == true) { + LpnTranList[] newCurEnabledArray = new LpnTranList[arraySize]; + for (int i = 0; i < arraySize; i++) + newCurEnabledArray[i] = new LpnTranList(); + + for (Transition tran : ampleSet) + newCurEnabledArray[tran.getLpn().getLpnIndex()].addLast(tran); + + sortedAmpleSet = new LpnTranList(); + for (int i = 0; i < arraySize; i++) { + LpnTranList localEnabledSet = newCurEnabledArray[i]; + for (Transition tran : localEnabledSet) + sortedAmpleSet.addLast(tran); + } + } + + +// for(LPNTran tran : original) +// System.out.print(tran.getFullLabel() + ", "); +// System.out.println("\n"); +// +// for(LPNTran tran : ampleSet) +// System.out.print(tran.getFullLabel() + ", "); +// System.out.println("\n"); +// System.out.println("\n ---------111111-------------\n"); + + +// for(LPNTran tran : firedTranStack.peek()) +// allCurEnabled.remove(tran); +// + lpnTranStack.pop(); + lpnTranStack.push(sortedAmpleSet); + +// for (int i = 0; i < arraySize; i++) { +// for (LPNTran tran : curEnabledArray[i]) { +// System.out.print(tran.getFullLabel() + ", "); +// } +// } +// System.out.println("\n"); +// +// for(LPNTran tran : allCurEnabled) +// System.out.print(tran.getFullLabel() + ", "); +// System.out.println("\n-------------------------\n"); + } + + //System.out.println("Backtrack........\n"); + }//END while (stateStack.empty() == false) + + + if (useMdd==true) + stateCount = Mdd.numberOfStates(reach); + else + stateCount = prjStateSet.size(); + + //long curTotalMem = Runtime.getRuntime().totalMemory(); + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + System.out.println("SUMMARY: # LPN transition firings: " + tranFiringCnt + + ", # of prjStates found: " + stateCount + + ", max_stack_depth: " + max_stack_depth + + ", used memory: " + (float) curUsedMem / 1000000 + + ", free memory: " + + (float) Runtime.getRuntime().freeMemory() / 1000000); + + return sgList; + } + +// /** +// * Check if this project deadlocks in the current state 'stateArray'. +// * @param sgList +// * @param stateArray +// * @param staticSetsMap +// * @param enableSet +// * @param disableByStealingToken +// * @param disableSet +// * @param init +// * @return +// */ +// // Called by search search_dfsPOR +// public boolean deadLock(StateGraph[] sgList, State[] stateArray, HashMap staticSetsMap, +// boolean init, HashMap tranFiringFreq, HashSet stateStack, PrjState stateStackTop, int cycleClosingMethdIndex) { +// boolean deadlock = true; +// System.out.println("@ deadlock:"); +//// for (int i = 0; i < stateArray.length; i++) { +//// LinkedList tmp = getAmple(stateArray, null, staticSetsMap, init, tranFiringFreq, sgList, stateStack, stateStackTop, cycleClosingMethdIndex).getAmpleSet(); +//// if (tmp.size() > 0) { +//// deadlock = false; +//// break; +//// } +//// } +// +// LinkedList tmp = getAmple(stateArray, null, staticSetsMap, init, tranFiringFreq, sgList, stateStack, stateStackTop, cycleClosingMethdIndex).getAmpleSet(); +// if (tmp.size() > 0) { +// deadlock = false; +// } +// System.out.println("@ end of deadlock"); +// return deadlock; +// } + + public static boolean deadLock(StateGraph[] lpnArray, State[] stateArray) { + boolean deadlock = true; + for (int i = 0; i < stateArray.length; i++) { + LinkedList tmp = lpnArray[i].getEnabled(stateArray[i]); + if (tmp.size() > 0) { + deadlock = false; + break; + } + } + return deadlock; + } + + public static boolean deadLock(StateGraph[] lpnArray, int[] stateIdxArray) { + boolean deadlock = true; + for (int i = 0; i < stateIdxArray.length; i++) { + LinkedList tmp = lpnArray[i].getEnabled(stateIdxArray[i]); + if (tmp.size() > 0) { + deadlock = false; + break; + } + } + + return deadlock; + } + + public static boolean deadLock(List> lpnList) { + boolean deadlock = true; + for (int i = 0; i < lpnList.size(); i++) { + LinkedList tmp = lpnList.get(i); + if (tmp.size() > 0) { + deadlock = false; + break; + } + } + return deadlock; + } + +// /* +// * Scan enabledArray, identify all sticky transitions other the firedTran, and return them. +// * +// * Arguments remain constant. +// */ +// +// public static LpnTranList[] getStickyTrans(LpnTranList[] enabledArray, Transition firedTran) { +// int arraySize = enabledArray.length; +// LpnTranList[] stickyTranArray = new LpnTranList[arraySize]; +// for (int i = 0; i < arraySize; i++) { +// stickyTranArray[i] = new LpnTranList(); +// for (Transition tran : enabledArray[i]) { +// if (tran != firedTran) +// stickyTranArray[i].add(tran); +// } +// +// if(stickyTranArray[i].size()==0) +// stickyTranArray[i] = null; +// } +// return stickyTranArray; +// } + + /** + * Identify if any sticky transitions in currentStickyTransArray can existing in the nextState. If so, add them to + * nextStickyTransArray. + * + * Arguments: curStickyTransArray and nextState are constant, nextStickyTransArray may be added with sticky transitions + * from curStickyTransArray. + * + * Return: sticky transitions from curStickyTransArray that are not marking disabled in nextState. + */ + public static LpnTranList[] checkStickyTrans( + LpnTranList[] curStickyTransArray, LpnTranList[] nextEnabledArray, + LpnTranList[] nextStickyTransArray, State nextState, LPN LPN) { + int arraySize = curStickyTransArray.length; + LpnTranList[] stickyTransArray = new LpnTranList[arraySize]; + boolean[] hasStickyTrans = new boolean[arraySize]; + + for (int i = 0; i < arraySize; i++) { + HashSet tmp = new HashSet(); + if(nextStickyTransArray[i] != null) + for(Transition tran : nextStickyTransArray[i]) + tmp.add(tran); + + + stickyTransArray[i] = new LpnTranList(); + hasStickyTrans[i] = false; + for (Transition tran : curStickyTransArray[i]) { + if (tran.isPersistent() == true && tmp.contains(tran)==false) { + int[] nextMarking = nextState.getMarking(); + int[] preset = LPN.getPresetIndex(tran.getLabel());//tran.getPreSet(); + boolean included = false; + if (preset != null && preset.length > 0) { + for (int pp : preset) { + for (int mi = 0; i < nextMarking.length; i++) { + if (nextMarking[mi] == pp) { + included = true; + break; + } + } + if (included == false) + break; + } + } + if(preset==null || preset.length==0 || included==true) { + stickyTransArray[i].add(tran); + hasStickyTrans[i] = true; + } + } + } + + if(stickyTransArray[i].size()==0) + stickyTransArray[i] = null; + } + + return stickyTransArray; + } + + /* + * Return an array of indices for the given stateArray. + */ + private static int[] getIdxArray(State[] stateArray) { + int[] idxArray = new int[stateArray.length]; + + for(int i = 0; i < stateArray.length; i++) { + idxArray[i] = stateArray[i].getIndex(); + } + return idxArray; + } + + private static int[] getLocalStateIdxArray(StateGraph[] sgList, State[] stateArray, boolean reverse) { + int arraySize = sgList.length; + int[] localIdxArray = new int[arraySize]; + + for(int i = 0; i < arraySize; i++) { + if(reverse == false) + localIdxArray[i] = sgList[i].getLocalState(stateArray[i]).getIndex(); + else + localIdxArray[arraySize - i - 1] = sgList[i].getLocalState(stateArray[i]).getIndex(); + + //System.out.print(localIdxArray[i] + " "); + } + //System.out.println(); + return localIdxArray; + } + + private static void printStrongStubbornSetTbl(StateGraph[] sgList) { + for (int i=0; i "); + printTransList(sgList[i].getEnabledSetTbl().get(s), ""); + } + } + } + + private HashSet computeStrongStubbornSet(State[] curStateArray, + HashSet curEnabled, HashMap tranFiringFreq, StateGraph[] sgList) { + if (curEnabled.size() == 1) + return curEnabled; + HashSet ready = new HashSet(); +// for (Transition enabledTran : curEnabled) { +// if (staticMap.get(enabledTran).getOtherTransDisableCurTranSet().isEmpty()) { +// ready.add(enabledTran); +// return ready; +// } +// } + DependentSetComparator depComp = new DependentSetComparator(tranFiringFreq, sgList.length-1); + PriorityQueue dependentSetQueue = new PriorityQueue(curEnabled.size(), depComp); + for (Transition enabledTran : curEnabled) { + if (Options.getDebugMode()) + System.out.println("@ beginning of partialOrderReduction, consider seed transition " + enabledTran.getFullLabel()); + HashSet dependent = new HashSet(); + boolean enabledIsDummy = false; + boolean isCycleClosingStrongStubbornComputation = false; + dependent = computeDependent(curStateArray,enabledTran,dependent,curEnabled,isCycleClosingStrongStubbornComputation); + if (Options.getDebugMode()) + printIntegerSet(dependent, "@ end of partialOrderReduction, dependent set for enabled transition " + + enabledTran.getFullLabel()); + // TODO: Immediate transition should have 0 delay, not "null" delay. +// // Check if the computed dependent set contains both immediate and non-immediate transitions. +// boolean dependentOnlyHasImmediateTrans = false; +// boolean dependentOnlyHasNonImmediateTrans = false; +// for (Transition tr: dependent) { +// if (!dependentOnlyHasImmediateTrans && tr.getDelayTree() == null) { +// dependentOnlyHasImmediateTrans = true; +// } +// if (!dependentOnlyHasNonImmediateTrans && tr.getDelayTree() != null) { +// dependentOnlyHasNonImmediateTrans = true; +// } +// } +// if (dependentOnlyHasNonImmediateTrans && dependentOnlyHasImmediateTrans) { +// System.err.println("*** Error: Non-immediate transitions are dependent on immediate ones. ***"); +// System.out.println("dependent set: "); +// for (Transition tr : dependent) { +// System.out.println(tr.getFullLabel()); +// } +// System.out.println(); +// } + // TODO: temporarily dealing with dummy transitions (This requires the dummy transitions to have "_dummy" in their names.) + if(isDummyTran(enabledTran.getLabel())) + enabledIsDummy = true; + DependentSet dependentSet = new DependentSet(dependent, enabledTran, enabledIsDummy); + dependentSetQueue.add(dependentSet); + } + ready = dependentSetQueue.poll().getDependent(); + +// for (Transition enabledTran : curEnabled) { +// if (Options.getDebugMode()) +// System.out.print("@ beginning of partialOrderReduction, consider seed transition " + getNamesOfLPNandTrans(enabledTran)); +// HashSet dependent = new HashSet(); +// boolean isCycleClosingPersistentComputation = false; +// dependent = computeDependent(curStateArray,enabledTran,dependent,curEnabled,isCycleClosingPersistentComputation); +// if (Options.getDebugMode()) { +// printIntegerSet(dependent, "@ end of partialOrderReduction, dependent set for enabled transition " +// + getNamesOfLPNandTrans(enabledTran)); +// } +// if (ready.isEmpty() || dependent.size() < ready.size()) +// ready = dependent; +// if (ready.size() == 1) { +// cachedNecessarySets.clear(); +// return ready; +// } +// } + cachedNecessarySets.clear(); + return ready; + } + +// private HashSet partialOrderReduction(State[] curStateArray, +// HashSet curEnabled, HashMap staticMap, +// HashMap tranFiringFreqMap, StateGraph[] sgList, LhpnFile[] lpnList) { +// if (curEnabled.size() == 1) +// return curEnabled; +// HashSet ready = new HashSet(); +// for (Transition enabledTran : curEnabled) { +// if (staticMap.get(enabledTran).getOtherTransDisableCurTranSet().isEmpty()) { +// ready.add(enabledTran); +// return ready; +// } +// } +// if (Options.getUseDependentQueue()) { +// DependentSetComparator depComp = new DependentSetComparator(tranFiringFreqMap); +// PriorityQueue dependentSetQueue = new PriorityQueue(curEnabled.size(), depComp); +// for (Transition enabledTran : curEnabled) { +// if (Options.getDebugMode()){ +// writeStringWithEndOfLineToPORDebugFile("@ beginning of partialOrderReduction, consider seed transition " + getNamesOfLPNandTrans(enabledTran)); +// } +// HashSet dependent = new HashSet(); +// boolean enabledIsDummy = false; +// boolean isCycleClosingPersistentComputation = false; +// dependent = computeDependent(curStateArray,enabledTran,dependent,curEnabled,staticMap,isCycleClosingPersistentComputation); +// if (Options.getDebugMode()) { +// writeIntegerSetToPORDebugFile(dependent, "@ end of partialOrderReduction, dependent set for enabled transition " +// + getNamesOfLPNandTrans(enabledTran)); +// } +// // TODO: temporarily dealing with dummy transitions (This requires the dummy transitions to have "_dummy" in their names.) +// if(isDummyTran(enabledTran.getName())) +// enabledIsDummy = true; +// DependentSet dependentSet = new DependentSet(dependent, enabledTran, enabledIsDummy); +// dependentSetQueue.add(dependentSet); +// } +// //cachedNecessarySets.clear(); +// ready = dependentSetQueue.poll().getDependent(); +// //return ready; +// } +// else { +// for (Transition enabledTran : curEnabled) { +// if (Options.getDebugMode()){ +// writeStringWithEndOfLineToPORDebugFile("@ beginning of partialOrderReduction, consider seed transition " + getNamesOfLPNandTrans(enabledTran)); +// } +// HashSet dependent = new HashSet(); +// boolean isCycleClosingPersistentComputation = false; +// dependent = computeDependent(curStateArray,enabledTran,dependent,curEnabled,staticMap,isCycleClosingPersistentComputation); +// if (Options.getDebugMode()) { +// writeIntegerSetToPORDebugFile(dependent, "@ end of partialOrderReduction, dependent set for enabled transition " +// + getNamesOfLPNandTrans(enabledTran)); +// } +// if (ready.isEmpty() || dependent.size() < ready.size()) +// ready = dependent;//(HashSet) dependent.clone(); +// if (ready.size() == 1) { +// cachedNecessarySets.clear(); +// return ready; +// } +// +// } +// } +// cachedNecessarySets.clear(); +// return ready; +// } + + private static boolean isDummyTran(String tranName) { + if (tranName.contains("_dummy")) + return true; + return false; + } + + private HashSet computeDependent(State[] curStateArray, Transition seed, HashSet dependent, + HashSet curEnabled, boolean isCycleClosingStrongStubbornComputation) { + // disableSet is the set of transitions that can either be disabled by firing enabledLpnTran, or disable enabledLpnTran. + boolean seedTranIsPersistent = false; + if (seed.isPersistent()) { + seedTranIsPersistent = true; + } + HashSet disableSet = staticDependency.get(seed).getDisableSet(seedTranIsPersistent); + HashSet otherTransDisableEnabledPeristentSeedTran + = staticDependency.get(seed).getOtherTransDisableSeedTran(seedTranIsPersistent); + if (Options.getDebugMode()) { + System.out.println("@ beginning of computeDependent, consider transition " + seed.getFullLabel()); + printIntegerSet(disableSet, "Disable set for " + seed.getFullLabel()); + } + dependent.add(seed); +// for (Transition lpnTranPair : canModifyAssign) { +// if (curEnabled.contains(lpnTranPair)) +// dependent.add(lpnTranPair); +// } + if (Options.getDebugMode()) + printIntegerSet(dependent, "@ computeDependent at 0, dependent set for " + seed.getFullLabel()); + // dependent is equal to enabled. Terminate. + if (dependent.size() == curEnabled.size()) { + if (Options.getDebugMode()) { + System.out.println("Check 0: Size of dependent is equal to enabled. Return dependent."); + } + return dependent; + } + for (Transition tr : disableSet) { + if (Options.getDebugMode()) + System.out.println("Consider transition in the disable set of " + + seed.getFullLabel() + ": " + + tr.getFullLabel()); + if (curEnabled.contains(tr) && !dependent.contains(tr) + && (!tr.isPersistent() || otherTransDisableEnabledPeristentSeedTran.contains(tr))) { + // (tr is enabled) && (tr is not in seed's dependent set) && (tr is not persistent || ) + dependent.addAll(computeDependent(curStateArray,tr,dependent,curEnabled,isCycleClosingStrongStubbornComputation)); + if (Options.getDebugMode()) { + printIntegerSet(dependent, "@ computeDependent at 1 for transition " + seed.getFullLabel()); + } + } + else if (!curEnabled.contains(tr)) { + if(Options.getPOR().toLowerCase().equals("tboff") // no trace-back + || (Options.getCycleClosingStrongStubbornMethd().toLowerCase().equals("cctboff") + && isCycleClosingStrongStubbornComputation)) { + dependent.addAll(curEnabled); + break; + } + HashSet necessary = null; + if (Options.getDebugMode()) { + printCachedNecessarySets(); + } + if (cachedNecessarySets.containsKey(tr)) { + if (Options.getDebugMode()) { + printCachedNecessarySets(); + System.out.println("@ computeDependent: Found transition " + tr.getFullLabel() + "in the cached necessary sets."); + } + necessary = cachedNecessarySets.get(tr); + } + else { + if (Options.getDebugMode()) + System.out.println("==== Compute necessary set using DFS ===="); + if (visitedTrans == null) + visitedTrans = new HashSet(); + else + visitedTrans.clear(); + necessary = computeNecessary(curStateArray,tr,dependent,curEnabled); + } + if (necessary != null && !necessary.isEmpty()) { + cachedNecessarySets.put(tr, necessary); + if (Options.getDebugMode()) + printIntegerSet(necessary, "@ computeDependent, necessary set for transition " + tr.getFullLabel()); + for (Transition tranInNecessary : necessary) { + if (!dependent.contains(tranInNecessary)) { + if (Options.getDebugMode()) { + printIntegerSet(dependent,"Check if the newly found necessary transition is in the dependent set of " + seed.getFullLabel()); + System.out.println("It does not contain this transition found by computeNecessary: " + + tranInNecessary.getFullLabel() + ". Compute its dependent set."); + } + dependent.addAll(computeDependent(curStateArray,tranInNecessary,dependent,curEnabled,isCycleClosingStrongStubbornComputation)); + } + else { + if (Options.getDebugMode()) { + printIntegerSet(dependent, "Check if the newly found necessary transition is in the dependent set. Dependent set for " + seed.getFullLabel()); + System.out.println("It already contains this transition found by computeNecessary: " + + tranInNecessary.getFullLabel() + "."); + } + } + } + } + else { + if (Options.getDebugMode()) { + if (necessary == null) + System.out.println("necessary set for transition " + seed.getFullLabel() + " is null."); + else + System.out.println("necessary set for transition " + seed.getFullLabel() + " is empty."); + } + //dependent.addAll(curEnabled); + return curEnabled; + } + if (Options.getDebugMode()) { + printIntegerSet(dependent,"@ computeDependent at 2, dependent set for transition " + seed.getFullLabel()); + } + } + else if (dependent.contains(tr)) { + if (Options.getDebugMode()) { + printIntegerSet(dependent,"@ computeDependent at 3 for transition " + seed.getFullLabel()); + System.out.println("Transition " + tr.getFullLabel() + " is already in the dependent set of " + + seed.getFullLabel() + "."); + } + } + } + return dependent; + } + +// private String getNamesOfLPNandTrans(Transition tran) { +// return tran.getLpn().getLabel() + "(" + tran.getLabel() + ")"; +// } + + private HashSet computeNecessary(State[] curStateArray, + Transition tran, HashSet dependent, + HashSet curEnabled) { + if (Options.getDebugMode()) { + System.out.println("@ computeNecessary, consider transition: " + tran.getFullLabel()); + } + if (cachedNecessarySets.containsKey(tran)) { + if (Options.getDebugMode()) { + printCachedNecessarySets(); + System.out.println("@ computeNecessary: Found transition " + tran.getFullLabel() + + "'s necessary set in the cached necessary sets. Return the cached necessary set."); + } + return cachedNecessarySets.get(tran); + } + // Search for transition(s) that can help to bring the marking(s). + HashSet nMarking = null; + //Transition transition = lpnList[tran.getLpnIndex()].getTransition(tran.getTranIndex()); + //int[] presetPlaces = lpnList[tran.getLpnIndex()].getPresetIndex(transition.getName()); + for (int i=0; i < tran.getPreset().length; i++) { + int placeIndex = tran.getLpn().getPresetIndex(tran.getLabel())[i]; + if (curStateArray[tran.getLpn().getLpnIndex()].getMarking()[placeIndex]==0) { + if (Options.getDebugMode()) { + System.out.println("####### compute nMarking for transition " + tran.getFullLabel() + "########"); + } + HashSet nMarkingTemp = new HashSet(); + String placeName = tran.getLpn().getPlaceList()[placeIndex]; + Transition[] presetTrans = tran.getLpn().getPlace(placeName).getPreset(); + if (Options.getDebugMode()) { + System.out.println("@ nMarking: Consider preset place of " + tran.getFullLabel() + ": " + placeName); + } + for (int j=0; j < presetTrans.length; j++) { + Transition presetTran = presetTrans[j]; + if (Options.getDebugMode()) { + System.out.println("@ nMarking: Preset of place " + placeName + " has transition(s): "); + for (int k=0; k tmp = computeNecessary(curStateArray, presetTran, dependent, curEnabled); + if (tmp != null) { + nMarkingTemp.addAll(tmp); + if (Options.getDebugMode()) { + System.out.println("@ nMarking: tmp returned from computeNecessary for " + presetTran.getFullLabel() + " is not null."); + printIntegerSet(nMarkingTemp, presetTran.getFullLabel() + "'s nMarkingTemp"); + } + } + else + if (Options.getDebugMode()) { + System.out.println("@ nMarking: necessary set for transition " + + presetTran.getFullLabel() + " is null."); + } + } + } + if (!nMarkingTemp.isEmpty()) + //if (nMarking == null || nMarkingTemp.size() < nMarking.size()) + if (nMarking == null + || setSubstraction(nMarkingTemp, dependent).size() < setSubstraction(nMarking, dependent).size()) + nMarking = nMarkingTemp; + } + else + if (Options.getDebugMode()) { + System.out.println("@ nMarking: Place " + tran.getLpn().getLabel() + + "(" + tran.getLpn().getPlaceList()[placeIndex] + ") is marked."); + } + } + if (nMarking != null && nMarking.size() ==1 && setSubstraction(nMarking, dependent).size() == 0) { + cachedNecessarySets.put(tran, nMarking); + if (Options.getDebugMode()) { + System.out.println("Return nMarking as necessary set."); + printCachedNecessarySets(); + } + return nMarking; + } + + // Search for transition(s) that can help to enable the current transition. + HashSet nEnable = null; + int[] varValueVector = curStateArray[tran.getLpn().getLpnIndex()].getVariableVector(); + //HashSet canEnable = staticMap.get(tran).getEnableBySettingEnablingTrue(); + ArrayList> canEnable = staticDependency.get(tran).getOtherTransSetSeedTranEnablingTrue(); + if (Options.getDebugMode()) { + System.out.println("####### compute nEnable for transition " + tran.getFullLabel() + "########"); + printIntegerSet(canEnable, "@ nEnable: " + tran.getFullLabel() + " can be enabled by"); + } + if (tran.getEnablingTree() != null + && tran.getEnablingTree().evaluateExpr(tran.getLpn().getAllVarsWithValuesAsString(varValueVector)) == 0.0 + && !canEnable.isEmpty()) { + for(int index=0; index < tran.getConjunctsOfEnabling().size(); index++) { + ExprTree conjunctExprTree = tran.getConjunctsOfEnabling().get(index); + HashSet nEnableForOneConjunct = null; + if (Options.getDebugMode()) { + printIntegerSet(canEnable, "@ nEnable: " + tran.getFullLabel() + " can be enabled by"); + System.out.println("@ nEnable: Consider conjunct for transition " + tran.getFullLabel() + ": " + + conjunctExprTree.toString()); + } + if (conjunctExprTree.evaluateExpr(tran.getLpn().getAllVarsWithValuesAsString(varValueVector)) == 0.0) { + HashSet canEnableOneConjunctSet = staticDependency.get(tran).getOtherTransSetSeedTranEnablingTrue().get(index); + nEnableForOneConjunct = new HashSet(); + if (Options.getDebugMode()) { + System.out.println("@ nEnable: Conjunct for transition " + tran.getFullLabel() + " " + + conjunctExprTree.toString() + " is evaluated to FALSE."); + printIntegerSet(canEnableOneConjunctSet, "@ nEnable: Transitions that can enable this conjunct are"); + } + for (Transition tranCanEnable : canEnableOneConjunctSet) { + if (curEnabled.contains(tranCanEnable)) { + nEnableForOneConjunct.add(tranCanEnable); + if (Options.getDebugMode()) { + System.out.println("@ nEnable: curEnabled contains transition " + tranCanEnable.getFullLabel() + ". Add to nEnableOfOneConjunct."); + } + } + else { + if (visitedTrans.contains(tranCanEnable)) { + if (Options.getDebugMode()) { + System.out.println("@ nEnable: Transition " + tranCanEnable.getFullLabel() + " was visted before."); + + } + if (cachedNecessarySets.containsKey(tranCanEnable)) { + if (Options.getDebugMode()) { + printCachedNecessarySets(); + System.out.println("@ nEnable: Found transition " + tranCanEnable.getFullLabel() + + "'s necessary set in the cached necessary sets. Add it to nEnableOfOneConjunct."); + } + nEnableForOneConjunct.addAll(cachedNecessarySets.get(tranCanEnable)); + } + continue; + } + visitedTrans.add(tranCanEnable); + if (Options.getDebugMode()) { + System.out.println("@ nEnable: Transition " + tranCanEnable.getFullLabel() + + " is not enabled. Compute its necessary set."); + } + HashSet tmp = computeNecessary(curStateArray, tranCanEnable, dependent, curEnabled); + if (tmp != null) { + nEnableForOneConjunct.addAll(tmp); + if (Options.getDebugMode()) { + System.out.println("@ nEnable: tmp returned from computeNecessary for " + tranCanEnable.getFullLabel() + ": "); + printIntegerSet(tmp, ""); + printIntegerSet(nEnableForOneConjunct, tranCanEnable.getFullLabel() + "'s nEnableOfOneConjunct"); + } + } + else + if (Options.getDebugMode()) { + System.out.println("@ nEnable: necessary set for transition " + + tranCanEnable.getFullLabel() + " is null."); + } + } + } + if (!nEnableForOneConjunct.isEmpty()) { + if (nEnable == null + || setSubstraction(nEnableForOneConjunct, dependent).size() < setSubstraction(nEnable, dependent).size()) { + //&& !nEnableForOneConjunct.isEmpty())) { + if (Options.getDebugMode()) { + System.out.println("@ nEnable: nEnable for transition " + tran.getFullLabel() +" is replaced by nEnableForOneConjunct."); + printIntegerSet(nEnable, "nEnable"); + printIntegerSet(nEnableForOneConjunct, "nEnableForOneConjunct"); + } + nEnable = nEnableForOneConjunct; + } + else { + if (Options.getDebugMode()) { + System.out.println("@ nEnable: nEnable for transition " + tran.getFullLabel() +" remains unchanged."); + printIntegerSet(nEnable, "nEnable"); + } + } + } + } + else { + if (Options.getDebugMode()) { + System.out.println("@ nEnable: Conjunct for transition " + tran.getFullLabel() + " " + + conjunctExprTree.toString() + " is evaluated to TRUE. No need to trace back on it."); + } + } + } + } + else { + if (Options.getDebugMode()) { + if (tran.getEnablingTree() == null) { + System.out.println("@ nEnable: transition " + tran.getFullLabel() + " has no enabling condition."); + } + else if (tran.getEnablingTree().evaluateExpr(tran.getLpn().getAllVarsWithValuesAsString(varValueVector)) !=0.0) { + System.out.println("@ nEnable: transition " + tran.getFullLabel() + "'s enabling condition is true."); + } + else if (tran.getEnablingTree() != null + && tran.getEnablingTree().evaluateExpr(tran.getLpn().getAllVarsWithValuesAsString(varValueVector)) == 0.0 + && canEnable.isEmpty()) { + System.out.println("@ nEnable: transition " + tran.getFullLabel() + + "'s enabling condition is false, but no other transitions that can help to enable it were found ."); + } + printIntegerSet(nMarking, "=== nMarking for transition " + tran.getFullLabel()); + printIntegerSet(nEnable, "=== nEnable for transition " + tran.getFullLabel()); + } + } + if (nMarking != null && nEnable == null) { + if (!nMarking.isEmpty()) + cachedNecessarySets.put(tran, nMarking); + if (Options.getDebugMode()) { + printCachedNecessarySets(); + } + return nMarking; + } + else if (nMarking == null && nEnable != null) { + if (!nEnable.isEmpty()) + cachedNecessarySets.put(tran, nEnable); + if (Options.getDebugMode()) { + printCachedNecessarySets(); + } + return nEnable; + } + else if (nMarking == null || nEnable == null) { + return null; + } + else { + if (!nMarking.isEmpty() && !nEnable.isEmpty()) { + if (setSubstraction(nMarking, dependent).size() < setSubstraction(nEnable, dependent).size()) { + cachedNecessarySets.put(tran, nMarking); + if (Options.getDebugMode()) { + printCachedNecessarySets(); + } + return nMarking; + } + cachedNecessarySets.put(tran, nEnable); + if (Options.getDebugMode()) { + printCachedNecessarySets(); + } + return nEnable; + } + else if (nMarking.isEmpty() && !nEnable.isEmpty()) { + cachedNecessarySets.put(tran, nEnable); + if (Options.getDebugMode()) { + printCachedNecessarySets(); + } + return nEnable; + } + else if (!nMarking.isEmpty() && nEnable.isEmpty()) { + cachedNecessarySets.put(tran, nMarking); + if (Options.getDebugMode()) { + printCachedNecessarySets(); + } + return nMarking; + } + else { + return null; + } + } + } + +// private HashSet computeNecessaryUsingDependencyGraphs(State[] curStateArray, +// Transition tran, HashSet curEnabled, +// HashMap staticMap, +// LhpnFile[] lpnList, Transition seedTran) { +// if (Options.getDebugMode()) { +//// System.out.println("@ computeNecessary, consider transition: " + lpnList[tran.getLpnIndex()].getLabel() + "(" + lpnList[tran.getLpnIndex()].getTransition(tran.getTranIndex()).getName() + ")"); +// writeStringWithEndOfLineToPORDebugFile("@ computeNecessary, consider transition: " + lpnList[tran.getLpnIndex()].getLabel() + "(" + lpnList[tran.getLpnIndex()].getTransition(tran.getTranIndex()).getName() + ")"); +// } +// // Use breadth-first search to find the shorted path from the seed transition to an enabled transition. +// LinkedList exploredTransQueue = new LinkedList(); +// HashSet allExploredTrans = new HashSet(); +// exploredTransQueue.add(tran); +// //boolean foundEnabledTran = false; +// HashSet canEnable = new HashSet(); +// while(!exploredTransQueue.isEmpty()){ +// Transition curTran = exploredTransQueue.poll(); +// allExploredTrans.add(curTran); +// if (cachedNecessarySets.containsKey(curTran)) { +// if (Options.getDebugMode()) { +// writeStringWithEndOfLineToPORDebugFile("Found transition " + lpnList[curTran.getLpnIndex()].getLabel() + "(" + lpnList[curTran.getLpnIndex()].getTransition(curTran.getTranIndex()).getName() + ")" +// + "'s necessary set in the cached necessary sets. Terminate BFS."); +// } +// return cachedNecessarySets.get(curTran); +// } +// canEnable = buildCanBringTokenSet(curTran,lpnList, curStateArray); +// if (Options.getDebugMode()) { +//// printIntegerSet(canEnable, lpnList, "Neighbors that can help to bring tokens to transition " + lpnList[curTran.getLpnIndex()].getLabel() + "(" + lpnList[curTran.getLpnIndex()].getTransition(curTran.getTranIndex()) + ") "); +// printIntegerSet(canEnable, lpnList, "Neighbors that can help to bring tokens to transition " + lpnList[curTran.getLpnIndex()].getLabel() + "(" + lpnList[curTran.getLpnIndex()].getTransition(curTran.getTranIndex()) + ") "); +// } +// // Decide if canSetEnablingTrue set can help to enable curTran. +// Transition curTransition = lpnList[curTran.getLpnIndex()].getTransition(curTran.getTranIndex()); +// int[] varValueVector = curStateArray[curTran.getLpnIndex()].getVector(); +// if (curTransition.getEnablingTree() != null +// && curTransition.getEnablingTree().evaluateExpr(lpnList[curTran.getLpnIndex()].getAllVarsWithValuesAsString(varValueVector)) == 0.0) { +// canEnable.addAll(staticMap.get(curTran).getEnableBySettingEnablingTrue()); +// if (Options.getDebugMode()) { +//// printIntegerSet(canEnable, lpnList, "Neighbors that can help to set the enabling of transition " + lpnList[curTran.getLpnIndex()].getLabel() + "(" + lpnList[curTran.getLpnIndex()].getTransition(curTran.getTranIndex()) + ") "); +// printIntegerSet(staticMap.get(curTran).getEnableBySettingEnablingTrue(), lpnList, "Neighbors that can help to set the enabling transition " + lpnList[curTran.getLpnIndex()].getLabel() + "(" + lpnList[curTran.getLpnIndex()].getTransition(curTran.getTranIndex()) + ") "); +// } +// } +// if (Options.getDebugMode()) { +//// printIntegerSet(canEnable, lpnList, "Neighbors that can help to enable transition " + lpnList[curTran.getLpnIndex()].getLabel() + "(" + lpnList[curTran.getLpnIndex()].getTransition(curTran.getTranIndex()) + ") "); +// printIntegerSet(canEnable, lpnList, "Neighbors that can help to enable transition " + lpnList[curTran.getLpnIndex()].getLabel() + "(" + lpnList[curTran.getLpnIndex()].getTransition(curTran.getTranIndex()) + ") "); +// } +// for (Transition neighborTran : canEnable) { +// if (curEnabled.contains(neighborTran)) { +// if (!neighborTran.equals(seedTran)) { +// HashSet necessarySet = new HashSet(); +// necessarySet.add(neighborTran); +// // TODO: Is it true that the necessary set for a disabled transition only contains a single element before the dependent set of the element is computed? +// cachedNecessarySets.put(tran, necessarySet); +// if (Options.getDebugMode()) { +//// System.out.println("Enabled neighbor that can help to enable transition " + lpnList[curTran.getLpnIndex()].getLabel() +//// + "(" + lpnList[curTran.getLpnIndex()].getTransition(curTran.getTranIndex()) + "): " + lpnList[neighborTran.getLpnIndex()].getLabel() +//// + "(" + lpnList[neighborTran.getLpnIndex()].getTransition(neighborTran.getTranIndex()) + ")."); +// writeStringWithEndOfLineToPORDebugFile("Enabled neighbor that can help to enable transition " + lpnList[curTran.getLpnIndex()].getLabel() +// + "(" + lpnList[curTran.getLpnIndex()].getTransition(curTran.getTranIndex()) + "): " + lpnList[neighborTran.getLpnIndex()].getLabel() +// + "(" + lpnList[neighborTran.getLpnIndex()].getTransition(neighborTran.getTranIndex()) + ")."); +// } +// return necessarySet; +// } +// else if (neighborTran.equals(seedTran) && canEnable.size()==1) { +// if (Options.getDebugMode()) { +//// System.out.println("Enabled neighbor that can help to enable transition " + lpnList[curTran.getLpnIndex()].getLabel() +//// + "(" + lpnList[curTran.getLpnIndex()].getTransition(curTran.getTranIndex()) + "): " + lpnList[neighborTran.getLpnIndex()].getLabel() +//// + "(" + lpnList[neighborTran.getLpnIndex()].getTransition(neighborTran.getTranIndex()) + "). But " + lpnList[neighborTran.getLpnIndex()].getLabel() +//// + "(" + lpnList[neighborTran.getLpnIndex()].getTransition(neighborTran.getTranIndex()) + ") is the seed transition. Return null necessary set."); +// writeStringWithEndOfLineToPORDebugFile("Enabled neighbor that can help to enable transition " + lpnList[curTran.getLpnIndex()].getLabel() +// + "(" + lpnList[curTran.getLpnIndex()].getTransition(curTran.getTranIndex()) + "): " + lpnList[neighborTran.getLpnIndex()].getLabel() +// + "(" + lpnList[neighborTran.getLpnIndex()].getTransition(neighborTran.getTranIndex()) + "). But " + lpnList[neighborTran.getLpnIndex()].getLabel() +// + "(" + lpnList[neighborTran.getLpnIndex()].getTransition(neighborTran.getTranIndex()) + ") is the seed transition. Return null necessary set."); +// } +// return null; +//// if (exploredTransQueue.isEmpty()) { +//// System.out.println("exploredTransQueue is empty. Return null necessary set."); +//// writeStringWithNewLineToPORDebugFile("exploredTransQueue is empty. Return null necessary set."); +//// return null; +//// } +// } +// } +// if (!allExploredTrans.contains(neighborTran)) { +// allExploredTrans.add(neighborTran); +// exploredTransQueue.add(neighborTran); +// } +// } +// canEnable.clear(); +// } +// return null; +// } + + private void printCachedNecessarySets() { + System.out.println("================ cached necessary sets ================="); + for (Transition key : cachedNecessarySets.keySet()) { + System.out.print(key.getLpn().getLabel() + "(" + key.getLabel() + ") => "); + for (Transition necessary : cachedNecessarySets.get(key)) { + System.out.print(necessary.getLpn().getLabel() + "(" + necessary.getLabel() + ") "); + } + System.out.println(""); + } + } + + private static HashSet setSubstraction( + HashSet left, HashSet right) { + HashSet sub = new HashSet(); + for (Transition lpnTranPair : left) { + if (!right.contains(lpnTranPair)) + sub.add(lpnTranPair); + } + return sub; + } + + public static boolean stateOnStack(int lpnIndex, State curState, HashSet stateStack) { + boolean isStateOnStack = false; + for (PrjState prjState : stateStack) { + State[] stateArray = prjState.toStateArray(); + if(stateArray[lpnIndex].equals(curState)) {// (stateArray[lpnIndex] == curState) { + isStateOnStack = true; + break; + } + } + return isStateOnStack; + } + + private static void printIntegerSet(HashSet Trans, String setName) { + if (!setName.isEmpty()) + System.out.print(setName + ": "); + if (Trans == null) { + System.out.println("null"); + } + else if (Trans.isEmpty()) { + System.out.println("empty"); + } + else { + for (Transition lpnTranPair : Trans) { + System.out.print(lpnTranPair.getLabel() + "(" + + lpnTranPair.getLpn().getLabel() + "),"); + } + System.out.println(); + } + } + + private static void printIntegerSet(ArrayList> transSet, String setName) { + if (!setName.isEmpty()) + System.out.print(setName + ": "); + if (transSet == null) { + System.out.println("null"); + } + else if (transSet.isEmpty()) { + System.out.println("empty"); + } + else { + for (HashSet lpnTranPairSet : transSet) { + for (Transition lpnTranPair : lpnTranPairSet) + System.out.print(lpnTranPair.getLpn().getLabel() + "(" + + lpnTranPair.getLabel() + "),"); + } + System.out.println(); + } + + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositeState.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositeState.java new file mode 100644 index 000000000..17f05a6e6 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositeState.java @@ -0,0 +1,200 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.logicAnalysis; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class CompositeState{ + private int[] stateTuple = null; + private List incomingStateTranList = new LinkedList(); + private List outgoingStateTranList = new LinkedList(); + private String label = null; + private int index = 0; + + public void addIncomingStateTran(CompositeStateTran incomingTran){ + this.incomingStateTranList.add(incomingTran); + } + + public boolean removeIncomingStateTran(CompositeStateTran incomingTran){ + return this.incomingStateTranList.remove(incomingTran); + } + + public boolean removeOutgoingStateTran(CompositeStateTran outgoingTran){ + return this.outgoingStateTranList.remove(outgoingTran); + } + + public List getIncomingStateTranList(){ + return this.incomingStateTranList; + } + + public void addOutgoingStateTran(CompositeStateTran outgoingTran){ + this.outgoingStateTranList.add(outgoingTran); + } + + public List getOutgoingStateTranList(){ + return this.outgoingStateTranList; + } + + public int numIncomingTrans(){ + return this.incomingStateTranList.size(); + } + + public int numOutgoingTrans(){ + return this.outgoingStateTranList.size(); + } + + public CompositeState(int[] stateArray){ + this.stateTuple = stateArray; + } + + /** + * Adds a state transition from this state. + * @param lpnTran - LPN transition causing the state transition + * @param cState - Next state + * @return The next CompositeState object already associated with the LPNTran, otherwise null. + */ +// public CompositeState addNextStateTran(LPNTran lpnTran, CompositeState cState){ +// return this.nextStateMap.put(lpnTran, cState); +// } + + /** + * Adds a state transition to this state. + * @param lpnTran - LPN transition causing the state transition + * @param cState - Previous state + * @return The previous CompositeState object already associated with the LPNTran, otherwise null. + */ +// public CompositeState addPreviousStateTran(LPNTran lpnTran, CompositeState cState){ +// return this.previousStateMap.put(lpnTran, cState); +// } + +// public void setTranArray(LPNTran[] tranArray){ +// this.tranArray = tranArray; +// } +// +// public LPNTran[] getTranArray(){ +// return this.tranArray; +// } +// +// public void setNextStateArray(CompositeState[] nextStateArray){ +// this.nextStateArray = nextStateArray; +// } +// +// public CompositeState[] getNextStateArray(){ +// return this.nextStateArray; +// } + + public void setLabel(String lbl){ + this.label = lbl; + } + + public String getLabel(){ + if(this.label == null){ + this.label = ""; + + for(int i = 0; i < this.stateTuple.length; i++){ + label += this.stateTuple[i]; + + if(i < this.stateTuple.length - 1){ + label += ","; + } + } + } + + return this.label; + } + + public void setIndex(int idx){ + this.index = idx; + } + + public int getIndex(){ + return this.index; + } + + public void clear(){ + this.outgoingStateTranList.clear(); + this.incomingStateTranList.clear(); + } + + @Override + public String toString(){ + return "" + getIndex(); + } + + public int getSize(){ + return this.stateTuple.length; + } + + public int[] getStateTuple(){ + return this.stateTuple; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(stateTuple); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CompositeState other = (CompositeState) obj; + if (!Arrays.equals(stateTuple, other.stateTuple)) + return false; + return true; + } + +// public void addEdge(CompositeStateTran edge){ +// this.edgeList.add(edge); +// } + +// public void addTran(LPNTran lpnTran){ +// this.tranList.add(lpnTran); +// } +// +// public void addNextState(CompositeState st){ +// this.nextStateList.add(st); +// } + +// public List getEdgeList(){ +// return this.edgeList; +// } + +// public List getTranList(){ +// return this.tranList; +// } +// +// public List getNextStateList(){ +// return this.nextStateList; +// } + + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositeStateGraph.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositeStateGraph.java new file mode 100644 index 000000000..c19b1c2f3 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositeStateGraph.java @@ -0,0 +1,330 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.logicAnalysis; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +import java.util.Set; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class CompositeStateGraph { + public Map indexStateMap = new HashMap(); + public Map stateMap = new HashMap(); + public Map stateTranMap = new HashMap(); + private StateGraph[] stateGraphArray = null; + private CompositeState initState = null; + private String label = ""; + + public StateGraph[] getStateGraphArray(){ + return this.stateGraphArray; + } + + public void setReachableStates(Map indexMap, Map stateMap){ + this.indexStateMap = indexMap; + this.stateMap = stateMap; + } + + public static List getEnabled(CompositeState currentState){ + //Set lpnTranSet = new HashSet(currentState.numOutgoingTrans()); + List enabled = new ArrayList(currentState.numOutgoingTrans()); + + /* + for(CompositeStateTran stTran : currentState.getOutgoingStateTranList()){ + // TODO: (future) Fix stTran.getLPNTran(). + Transition lpnTran = null; //stTran.getLPNTran(); + if(lpnTranSet.add(lpnTran)) + enabled.add(lpnTran); + } + */ + + return enabled; + } + + public CompositeState getState(int index){ + return this.indexStateMap.get(index); + } + + public CompositeStateTran addStateTran(CompositeState currentState, CompositeState nextState, Transition lpnTran){ + CompositeStateTran stateTran = new CompositeStateTran(currentState, nextState, lpnTran); + + CompositeStateTran tmpTran = this.stateTranMap.get(stateTran); + if(tmpTran != null){ + return tmpTran; + } + + this.stateTranMap.put(stateTran, stateTran); + currentState.addOutgoingStateTran(stateTran); + nextState.addIncomingStateTran(stateTran); + + return stateTran; + } + + public CompositeStateTran addStateTran(int currentStateIndex, int nextStateIndex, Transition lpnTran){ + CompositeState currentState = this.indexStateMap.get(currentStateIndex); + CompositeState nextState = this.indexStateMap.get(nextStateIndex); + CompositeStateTran stateTran = new CompositeStateTran(currentState, nextState, lpnTran); + + CompositeStateTran tmpTran = this.stateTranMap.get(stateTran); + if(tmpTran != null){ + return tmpTran; + } + + this.stateTranMap.put(stateTran, stateTran); + currentState.addOutgoingStateTran(stateTran); + nextState.addIncomingStateTran(stateTran); + + return stateTran; + } + + public CompositeStateTran addStateTran(CompositeStateTran stateTran){ + CompositeStateTran tmpTran = this.stateTranMap.get(stateTran); + if(tmpTran != null){ + return tmpTran; + } + + this.stateTranMap.put(stateTran, stateTran); + CompositeState currentState = this.getState(stateTran.getCurrentState()); + CompositeState nextState = this.getState(stateTran.getNextState()); + + currentState.addOutgoingStateTran(stateTran); + nextState.addIncomingStateTran(stateTran); + + return stateTran; + } + + public void removeStateTran(CompositeStateTran stateTran){ + if(this.stateTranMap.remove(stateTran) == null){ + return; + } + + CompositeState currentState = this.getState(stateTran.getCurrentState()); + CompositeState nextState = this.getState(stateTran.getNextState()); + + currentState.removeOutgoingStateTran(stateTran); + nextState.removeIncomingStateTran(stateTran); + } + + public boolean removeState(CompositeState st){ + CompositeState retState = this.stateMap.remove(st); + if(retState == null){ + return false; + } + + this.indexStateMap.remove(st.getIndex()); + + return true; + } + + public boolean removeState(int stateIndex){ + CompositeState retState = this.indexStateMap.remove(stateIndex); + if(retState == null){ + return false; + } + + this.stateMap.remove(retState); + + return true; + } + + public CompositeStateGraph(CompositeState initialState, StateGraph[] sgArray){ + this.initState = initialState; + this.stateGraphArray = sgArray; + + //int size = 0; + for(int i = 0; i < sgArray.length; i++){ + label += sgArray[i].getLpn().getLabel(); + + if(i < sgArray.length - 1){ + label += "||"; + } + + //size *= sgArray[i].reachSize(); + } + + this.addState(this.initState); + } + + public CompositeStateGraph(StateGraph sg){ + int[] initStateArray = new int[1]; + initStateArray[0] = sg.getInitialState().getIndex(); + CompositeState init = new CompositeState(initStateArray); + + StateGraph[] sgArray = new StateGraph[1]; + sgArray[0] = sg; + + // initialize attributes + this.initState = init; + this.stateGraphArray = sgArray; + + // construct label + //int size = 0; + for(int i = 0; i < sgArray.length; i++){ + label += sgArray[i].getLpn().getLabel(); + + if(i < sgArray.length - 1){ + label += "||"; + } + + //size *= sgArray[i].reachSize(); + } + + this.addState(this.initState); + + CompositeState tempState = null; + for(int i = 0; i < sg.reachSize(); i++){ + State currentState = sg.getState(i); +// for(State currentState : sg.getStateSet()){ + int[] currentStateArray = new int[1]; + currentStateArray[0] = currentState.getIndex(); + + CompositeState currentCompositeState = new CompositeState(currentStateArray); + tempState = this.addState(currentCompositeState); + if(tempState != currentCompositeState){ + currentCompositeState = tempState; + } + + Set> stateSet = sg.getOutgoingTrans(currentState); + for(Entry stateTran : stateSet){ + State nextState = stateTran.getValue(); + Transition lpnTran = stateTran.getKey(); + int[] nextStateArray = new int[1]; + nextStateArray[0] = nextState.getIndex(); + + CompositeState nextCompositeState = new CompositeState(nextStateArray); + tempState = this.addState(nextCompositeState); + if(tempState != nextCompositeState){ + nextCompositeState = tempState; + } + + CompositeStateTran newStateTran = new CompositeStateTran(currentCompositeState, nextCompositeState, lpnTran); + this.addStateTran(newStateTran); + if(!lpnTran.isLocal()){ + newStateTran.setVisibility(); + } + } + } + } + + public Set getStateSet(){ + return this.stateMap.keySet(); + } + + public int getSize(){ + return this.stateGraphArray.length; + } + + public String getLabel(){ + return this.label; + } + + /** + * Adds a composite state to the composite state graph + * @param st - CompositeState to be added + * @return Equivalent CompositeState object it exists, otherwise CompositeState st. + */ + public CompositeState addState(CompositeState st){ + CompositeState retState = this.stateMap.get(st); + if(retState == null){ + int index = this.indexStateMap.size(); + st.setIndex(index); + this.indexStateMap.put(index, st); + this.stateMap.put(st, st); + + return st; + } + + return retState; + } + + public final CompositeState getInitState(){ + return this.initState; + } + + public void setInitState(CompositeState init){ + this.initState = init; + } + + public int numStates(){ + return this.stateMap.size(); + } + + public int numStateTrans(){ + return this.stateTranMap.size(); + } + + public Set getStateTranSet(){ + return this.stateTranMap.keySet(); + } + + public boolean containsState(int stateIndex){ + return this.indexStateMap.containsKey(stateIndex); + } + + public boolean containsStateTran(CompositeStateTran stateTran){ + return this.stateTranMap.containsKey(stateTran); + } + + public void draw(){ + String dotFile = Options.getDotPath(); + if(!dotFile.endsWith("/") && !dotFile.endsWith("\\")){ + String dirSlash = "/"; + if(System.getProperty("os.name").toLowerCase().contains("windows")) dirSlash = "\\"; + + dotFile = dotFile += dirSlash; + } + + dotFile += this.label + ".dot"; + PrintStream graph = null; + + try { + graph = new PrintStream(new FileOutputStream(dotFile)); + } catch (FileNotFoundException e1) { + e1.printStackTrace(); + return; + } + + graph.println("digraph SG{"); + + for(CompositeState currentState : this.stateMap.keySet()){ + for(CompositeStateTran stateTran : currentState.getOutgoingStateTranList()){ + CompositeState nextState = this.indexStateMap.get(stateTran.getNextState()); + Transition lpnTran = stateTran.getLPNTran(); +// System.out.println(" " + nextState.getIndex()); + graph.println(" \"" + currentState.getIndex() + "\" " + " -> " + "\"" + nextState.getIndex() + "\"" + " [label=\"" + lpnTran.getFullLabel() + "\"]"); + } + } + + graph.println("}"); + graph.close(); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositeStateTran.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositeStateTran.java new file mode 100644 index 000000000..0b8b8b04e --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositeStateTran.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.logicAnalysis; + +import edu.utah.ece.async.lema.verification.lpn.Transition; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class CompositeStateTran { + private int nextState = 0; + private int currentState = 0; + private Transition lpnTransition = null; + private boolean visible = false; + + public CompositeStateTran(CompositeState currentState, CompositeState nextState, Transition lpnTran){ + this.currentState = currentState.getIndex(); + this.nextState = nextState.getIndex(); + this.lpnTransition = lpnTran; + } + + public CompositeStateTran(int currentState, int nextState, Transition lpnTransition){ + this.currentState = currentState; + this.nextState = nextState; + this.lpnTransition = lpnTransition; + } + + public void setVisibility(){ + this.visible = true; + } + + public boolean visible(){ + return this.visible; + } + + public void setCurrentState(int currState){ + this.currentState = currState; + } + + public void setNextState(int nxtState){ + this.nextState = nxtState; + } + + public void setLpnTran(Transition lpnTran){ + this.lpnTransition = lpnTran; + } + + public int getCurrentState(){ + return this.currentState; + } + + public int getNextState(){ + return this.nextState; + } + + public Transition getLPNTran(){ + return this.lpnTransition; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + this.nextState; + result = prime * result + this.lpnTransition.hashCode(); + result = prime * result + this.currentState; + + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + + if (obj == null) + return false; + + if (getClass() != obj.getClass()) + return false; + + CompositeStateTran other = (CompositeStateTran) obj; + if (this.nextState != other.nextState) + return false; + + if (this.lpnTransition != other.lpnTransition) + return false; + + if (this.currentState != other.currentState) + return false; + + return true; + } + + @Override + public String toString(){ + return (this.currentState + " --" + this.lpnTransition.getFullLabel() + "--> " + this.nextState); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositionalAnalysis.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositionalAnalysis.java new file mode 100644 index 000000000..b8ac51ae3 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/CompositionalAnalysis.java @@ -0,0 +1,2963 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.logicAnalysis; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.Stack; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.common.Pair; +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.platuLpn.VarSet; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class CompositionalAnalysis { + public CompositionalAnalysis(){ + } + +// public CompositeStateGraph compose(StateGraph sg1, StateGraph sg2){ +// long start = System.currentTimeMillis(); +// +// // check an output drives an input +// boolean compatible = false; +// for(String output : sg1.getOutputs()){ +// VarSet inputs = sg2.getInputs(); +// if(inputs.contains(output)){ +// compatible = true; +// break; +// } +// } +// +// if(!compatible){ +// VarSet inputs = sg1.getInputs(); +// for(String output : sg2.getOutputs()){ +// if(inputs.contains(output)){ +// compatible = true; +// break; +// } +// } +// } +// +// if(!compatible){ +// System.out.println("state graphs " + sg1.getLabel() + " and " + sg2.getLabel() + " cannot be composed\n"); +// return null; +// } +// +// // create new node with init states +// State[] initStates = new State[2]; +// initStates[0] = sg1.getInitialState(); +// initStates[1] = sg2.getInitialState(); +// CompositeState initNode = new CompositeState(initStates); +// +// HashSet synchronousTrans = new HashSet(); +// synchronousTrans.addAll(sg1.getInputTranSet()); +// synchronousTrans.retainAll(sg2.getOutputTranSet()); +// +// HashSet temp = new HashSet(); +// temp.addAll(sg2.getInputTranSet()); +// temp.retainAll(sg1.getOutputTranSet()); +// synchronousTrans.addAll(temp); +// +// List inputTrans1 = new ArrayList(); +// inputTrans1.addAll(sg1.getInputTranSet()); +// inputTrans1.removeAll(synchronousTrans); +// +// List inputTrans2 = new ArrayList(); +// inputTrans2.addAll(sg2.getInputTranSet()); +// inputTrans2.removeAll(synchronousTrans); +// +// // create new composite state graph +// StateGraph[] sgArray = new StateGraph[2]; +// sgArray[0] = sg1; +// sgArray[1] = sg2; +// CompositeStateGraph compositeSG = new CompositeStateGraph(initNode, sgArray); +// +// // create CompositeState stack +// Stack compositeStateStack = new Stack(); +// +// // initialize with initial MDD node +// compositeStateStack.push(initNode); +// +// List tranList1 = new ArrayList(); +// List stateList1 = new ArrayList(); +// List tranList2 = new ArrayList(); +// List stateList2 = new ArrayList(); +// List intersect1 = new ArrayList(); +// List intersect2 = new ArrayList(); +// List intersectTran = new ArrayList(); +// +// long peakUsed = 0; +// long peakTotal = 0; +// +// //while stack is not empty +// while(!compositeStateStack.isEmpty()){ +// //pop stack +// CompositeState currentCompositeState = compositeStateStack.pop(); +// +// State[] stateTuple = currentCompositeState.getStateTuple(); +// State s1 = stateTuple[0]; +// State s2 = stateTuple[1]; +// +// // find next state transitions for each state +//// LPNTranSet enabled1 = sg1.getEnabled(s1); +//// LPNTranSet enabled2 = sg2.getEnabled(s2); +// List enabled1 = sg1.lpnTransitionMap.get(s1); +// List enabled2 = sg2.lpnTransitionMap.get(s2); +// +// tranList1.clear(); +// stateList1.clear(); +// tranList2.clear(); +// stateList2.clear(); +// intersect1.clear(); +// intersect2.clear(); +// intersectTran.clear(); +// +// for(LPNTran lpnTran : enabled1){ +// if(lpnTran.local()){ +// tranList1.add(lpnTran); +// stateList1.add((State) lpnTran.getNextState(s1)); +// } +// else{ +// if(synchronousTrans.contains(lpnTran)){ +//// State st = lpnTran.constraintTranMap.get(s2); +// State st = lpnTran.getNextState(s2); +// if(st != null){ +// intersect1.add((State) lpnTran.getNextState(s1)); +// intersect2.add(st); +// intersectTran.add(lpnTran); +// } +// } +// else{ +// tranList1.add(lpnTran); +// stateList1.add((State) lpnTran.getNextState(s1)); +// } +// } +// } +// +// +// for(LPNTran lpnTran : enabled2){ +// if(lpnTran.local()){ +// tranList2.add(lpnTran); +// stateList2.add((State) lpnTran.getNextState(s2)); +// } +// else{ +// if(synchronousTrans.contains(lpnTran)){ +//// State st = lpnTran.constraintTranMap.get(s1); +// State st = lpnTran.getNextState(s1); +// if(st != null){ +// intersect1.add(st); +// intersect2.add((State) lpnTran.getNextState(s2)); +// intersectTran.add(lpnTran); +// } +// } +// else{ +// tranList2.add(lpnTran); +// stateList2.add((State) lpnTran.getNextState(s2)); +// } +// } +// } +// +// for(LPNTran lpnTran : inputTrans1){ +//// State st = lpnTran.constraintTranMap.get(s1); +// State st = lpnTran.getNextState(s1); +// if(st != null){ +// tranList1.add(lpnTran); +// stateList1.add(st); +// } +// } +// +// for(LPNTran lpnTran : inputTrans2){ +//// State st = lpnTran.constraintTranMap.get(s2); +// State st = lpnTran.getNextState(s2); +// if(st != null){ +// tranList2.add(lpnTran); +// stateList2.add(st); +// } +// } +// +//// int size = tranList1.size() + tranList2.size() + intersect1.size(); +//// CompositeState[] nextStateArray = new CompositeState[size]; +//// LPNTran[] tranArray = new LPNTran[size]; +//// size--; +// +// // for each transition +// // create new MDD node and push onto stack +// for(int i = 0; i < tranList1.size(); i++){ +// LPNTran lpnTran = tranList1.get(i); +// +// State nextState = stateList1.get(i); +// State[] newStateTuple = new State[2]; +// newStateTuple[0] = nextState; +// newStateTuple[1] = s2; +// +// CompositeState newCompositeState = new CompositeState(newStateTuple); +// CompositeState st = compositeSG.addState(newCompositeState); +// if(st == null){ +// compositeStateStack.push(newCompositeState); +// st = newCompositeState; +// } +// +// // create a new CompositeStateTran +//// CompositeStateTran newCompositeStateTran = new CompositeStateTran(currentCompositeState, st, lpnTran); +//// if(compositeSG.addStateTran(newCompositeStateTran)){ +// // add an edge between the current and new state +//// currentCompositeState.addEdge(newCompositeStateTran); +//// } +// +//// nextStateArray[size] = st; +//// tranArray[size] = lpnTran; +//// size--; +// +//// currentCompositeState.addNextState(st); +//// currentCompositeState.addTran(lpnTran); +// +// currentCompositeState.nextStateList.add(st); +// currentCompositeState.enabledTranList.add(lpnTran); +// st.incomingStateList.add(currentCompositeState); +// } +// +// for(int i = 0; i < tranList2.size(); i++){ +// LPNTran lpnTran = tranList2.get(i); +// +// State nextState = stateList2.get(i); +// State[] newStateTuple = new State[2]; +// newStateTuple[0] = s1; +// newStateTuple[1] = nextState; +// +// CompositeState newCompositeState = new CompositeState(newStateTuple); +// CompositeState st = compositeSG.addState(newCompositeState); +// if(st == null){ +// compositeStateStack.push(newCompositeState); +// st = newCompositeState; +// } +// +// // create new CompositeStateTran +//// CompositeStateTran newCompositeStateTran = new CompositeStateTran(currentCompositeState, st, lpnTran); +//// if(compositeSG.addStateTran(newCompositeStateTran)){ +// // add an edge between the current and new state +//// currentCompositeState.addEdge(newCompositeStateTran); +//// } +// +//// nextStateArray[size] = st; +//// tranArray[size] = lpnTran; +//// size--; +// +//// currentCompositeState.addNextState(st); +//// currentCompositeState.addTran(lpnTran); +// +// currentCompositeState.nextStateList.add(st); +// currentCompositeState.enabledTranList.add(lpnTran); +// st.incomingStateList.add(currentCompositeState); +// } +// +// for(int i = 0; i < intersect1.size(); i++){ +// LPNTran lpnTran = intersectTran.get(i); +// +// State nextState1 = intersect1.get(i); +// State nextState2 = intersect2.get(i); +// +// State[] newStateTuple = new State[2]; +// newStateTuple[0] = nextState1; +// newStateTuple[1] = nextState2; +// +// CompositeState newCompositeState = new CompositeState(newStateTuple); +// CompositeState st = compositeSG.addState(newCompositeState); +// if(st == null){ +// compositeStateStack.push(newCompositeState); +// st = newCompositeState; +// } +// +// // create a new CompositeStateTran +//// CompositeStateTran newCompositeStateTran = new CompositeStateTran(currentCompositeState, st, lpnTran); +//// if(compositeSG.addStateTran(newCompositeStateTran)){ +// // add an edge between the current and new state +//// currentCompositeState.addEdge(newCompositeStateTran); +//// } +// +//// nextStateArray[size] = st; +//// tranArray[size] = lpnTran; +//// size--; +// +//// currentCompositeState.addNextState(st); +//// currentCompositeState.addTran(lpnTran); +// +// currentCompositeState.nextStateList.add(st); +// currentCompositeState.enabledTranList.add(lpnTran); +// st.incomingStateList.add(currentCompositeState); +// } +// +//// currentCompositeState.setNextStateArray(nextStateArray); +//// currentCompositeState.setTranArray(tranArray); +// +// long curTotalMem = Runtime.getRuntime().totalMemory(); +// if(curTotalMem > peakTotal) +// peakTotal = curTotalMem; +// +// long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); +// if(curUsedMem > peakUsed) +// peakUsed = curUsedMem; +// } +// +// System.out.println("\n " + compositeSG.getLabel() + ": "); +// System.out.println(" --> # states: " + compositeSG.numCompositeStates()); +//// System.out.println(" --> # transitions: " + compositeSG.numCompositeStateTrans()); +// +// System.out.println(" --> Peak used memory: " + peakUsed/1000000F + " MB"); +// System.out.println(" --> Peak total memory: " + peakTotal/1000000F + " MB"); +// System.out.println(" --> Final used memory: " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1000000F + " MB"); +// +// long elapsedTimeMillis = System.currentTimeMillis()-start; +// float elapsedTimeSec = elapsedTimeMillis/1000F; +// System.out.println(" --> Elapsed time: " + elapsedTimeSec + " sec"); +// +// if(elapsedTimeSec > 60){ +// float elapsedTime = elapsedTimeSec; +// elapsedTime = elapsedTimeSec/(float)60; +// System.out.println(" --> Elapsed time: " + elapsedTime + " min"); +// } +// +// System.out.println(); +// +//// System.out.println(); +//// for(CompositeState cState : compositeSG.compositeStateMap){ +//// State[] stateTuple = cState.getStateTuple(); +//// State s1 = stateTuple[0]; +//// State s2 = stateTuple[1]; +//// +//// System.out.println(s1.getLabel() + ", " + s2.getLabel()); +//// } +// +// return compositeSG; +// } +// +// public CompositeStateGraph compose(CompositeStateGraph csg, StateGraph sg){ +// if(csg == null || sg == null){ +// return csg; +// } +// +// long start = System.currentTimeMillis(); +// +// // check an output drives an input +// boolean compatible = false; +// for(String output : sg.getOutputs()){ +// for(StateGraph sg2 : csg.stateGraphArray){ +// VarSet inputs = sg2.getInputs(); +// if(inputs.contains(output)){ +// compatible = true; +// break; +// } +// } +// +// if(compatible){ +// break; +// } +// } +// +// if(!compatible){ +// VarSet inputs = sg.getInputs(); +// for(StateGraph sg2 : csg.stateGraphArray){ +// for(String output : sg2.getOutputs()){ +// if(inputs.contains(output)){ +// compatible = true; +// break; +// } +// } +// +// if(compatible){ +// break; +// } +// } +// +// } +// +// if(!compatible){ +// System.out.println("state graphs " + csg.getLabel() + " and " + sg.getLabel() + " cannot be composed"); +// return null; +// } +// +// for(StateGraph sg2 : csg.stateGraphArray){ +// if(sg2 == sg){ +// return csg; +// } +// } +// +// // create new node with init states +// int size = csg.getSize() + 1; +// State[] initStates = new State[size]; +// initStates[0] = sg.getInitialState(); +// for(int i = 1; i < size; i++){ +// initStates[i] = csg.stateGraphArray[i-1].getInitialState(); +// } +// +// CompositeState initNode = new CompositeState(initStates); +// +// HashSet synchronousTrans = new HashSet(); +// +// for(StateGraph sg2 : csg.stateGraphArray){ +// HashSet inputTrans = new HashSet(); +// inputTrans.addAll(sg.getInputTranSet()); +// inputTrans.retainAll(sg2.getOutputTranSet()); +// +// HashSet outputTrans = new HashSet(); +// outputTrans.addAll(sg2.getInputTranSet()); +// outputTrans.retainAll(sg.getOutputTranSet()); +// +// synchronousTrans.addAll(inputTrans); +// synchronousTrans.addAll(outputTrans); +// } +// +// List inputTrans = new ArrayList(); +// inputTrans.addAll(sg.getInputTranSet()); +// inputTrans.removeAll(synchronousTrans); +// +// // create new composite state graph +// StateGraph[] sgArray = new StateGraph[size]; +// sgArray[0] = sg; +// for(int i = 1; i < size; i++){ +// sgArray[i] = csg.stateGraphArray[i-1]; +// } +// +// CompositeStateGraph compositeSG = new CompositeStateGraph(initNode, sgArray); +// +// // create CompositeState stack +// Stack stateStack = new Stack(); +// Stack compositeStateStack = new Stack(); +// Stack newStateStack = new Stack(); +// +//// Queue stateQueue = new LinkedList(); +//// Queue compositeStateQueue = new LinkedList(); +//// Queue newStateQueue = new LinkedList(); +// +// // initialize with initial MDD node +// newStateStack.push(initNode); +// stateStack.push(sg.getInitialState()); +// compositeStateStack.push(csg.getInitState()); +// +//// stateQueue.offer(sg.init); +//// compositeStateQueue.offer(csg.getInitState()); +//// newStateQueue.offer(initNode); +// +//// HashMap tranMap = new HashMap(); +//// List csgStateTranList = new ArrayList(); +//// List sgIntersect = new ArrayList(); +//// List csgIntersect = new ArrayList(); +// +// List tranList1 = new ArrayList(); +// List stateList1 = new ArrayList(); +// List tranList2 = new ArrayList(); +// List stateList2 = new ArrayList(); +// List intersect1 = new ArrayList(); +// List intersect2 = new ArrayList(); +// List intersectTran = new ArrayList(); +// +// long peakUsed = 0; +// long peakTotal = 0; +// +// //while stack is not empty +// while(!newStateStack.isEmpty()){ +//// while(!newStateQueue.isEmpty()){ +// long s1 = System.currentTimeMillis(); +// +// //pop stack +// CompositeState currentCompositeState = newStateStack.pop(); +// State subState = stateStack.pop(); +// CompositeState subCompositeState = compositeStateStack.pop(); +// +//// CompositeState currentCompositeState = newStateQueue.poll(); +//// State subState = stateQueue.poll(); +//// CompositeState subCompositeState = compositeStateQueue.poll(); +// +// State[] subCompositeTuple = subCompositeState.getStateTuple(); +// +// tranList1.clear(); +// stateList1.clear(); +// tranList2.clear(); +// stateList2.clear(); +// intersect1.clear(); +// intersect2.clear(); +// intersectTran.clear(); +// +// // find next state transitions for each state +// List enabled1 = sg.lpnTransitionMap.get(subState); +//// List enabled2 = subCompositeState.getTranList(); +//// List edgeList = subCompositeState.getNextStateList(); +//// LPNTran[] enabled2 = subCompositeState.getTranArray(); +//// CompositeState[] edgeList = subCompositeState.getNextStateArray(); +// List enabled2 = subCompositeState.enabledTranList; +// List edgeList = subCompositeState.nextStateList; +// +//// System.out.println(" enabled1: " + enabled1.size()); +// for(LPNTran lpnTran : enabled1){ +// if(lpnTran.local()){ +// tranList1.add(lpnTran); +// stateList1.add((State) lpnTran.getNextState(subState)); +// } +// else{ +// if(synchronousTrans.contains(lpnTran)){ +// boolean synch = false; +// CompositeState st = null; +// for(int i = 0; i < enabled2.size(); i++){ +// if(enabled2.get(i) == lpnTran){ +// synch = true; +// st = edgeList.get(i); +// break; +// } +// } +// +// if(synch){ +// intersect1.add((State) lpnTran.getNextState(subState)); +// intersect2.add(st); +// intersectTran.add(lpnTran); +// } +// else{ +// System.out.println("ST == NULL1\n"); +// } +// } +// else{ +// tranList1.add(lpnTran); +// stateList1.add((State) lpnTran.getNextState(subState)); +// } +// } +// } +// +//// System.out.println(" enabled2: " + enabled2.size()); +// for(int i = 0; i < enabled2.size(); i++){ +// LPNTran lpnTran = enabled2.get(i); +// +// if(synchronousTrans.contains(lpnTran)){ +//// State st = lpnTran.constraintTranMap.get(subState); +// State st = lpnTran.getNextState(subState); +// if(st != null){ +// intersectTran.add(lpnTran); +// intersect1.add(st); +// intersect2.add(edgeList.get(i)); +// } +// } +// else{ +// tranList2.add(lpnTran); +// stateList2.add(edgeList.get(i)); +// } +// } +// +//// System.out.println(" inputTrans: " + inputTrans.size()); +// for(LPNTran lpnTran : inputTrans){ +//// State st = lpnTran.constraintTranMap.get(subState); +// State st = lpnTran.getNextState(subState); +// if(st != null){ +// tranList1.add(lpnTran); +// stateList1.add(st); +// } +// } +// +//// int items = tranList1.size() + tranList2.size() + intersect1.size(); +//// CompositeState[] nextStateArray = new CompositeState[items]; +//// LPNTran[] tranArray = new LPNTran[items]; +//// items--; +// +// long s2 = System.currentTimeMillis(); +// // for each transition +// // create new MDD node and push onto stack +// for(int i = 0; i < tranList1.size(); i++){ +// LPNTran lpnTran = tranList1.get(i); +// State nextState = stateList1.get(i); +// State[] newStateTuple = new State[size]; +// newStateTuple[0] = nextState; +// for(int j = 1; j < size; j++){ +// newStateTuple[j] = subCompositeTuple[j-1]; +// } +// +// CompositeState newCompositeState = new CompositeState(newStateTuple); +// CompositeState st = compositeSG.addState(newCompositeState); +// if(st == null){ +// newStateStack.push(newCompositeState); +// stateStack.push(nextState); +// compositeStateStack.push(subCompositeState); +//// newStateQueue.offer(newCompositeState); +//// stateQueue.offer(nextState); +//// compositeStateQueue.offer(subCompositeState); +// +// st = newCompositeState; +// } +// +// // create a new CompositeStateTran +//// CompositeStateTran newCompositeStateTran = new CompositeStateTran(currentCompositeState, st, lpnTran); +//// if(compositeSG.addStateTran(newCompositeStateTran)){ +// // add an edge between the current and new state +//// currentCompositeState.addEdge(newCompositeStateTran); +//// } +// +//// nextStateArray[items] = st; +//// tranArray[items] = lpnTran; +//// items--; +// +//// currentCompositeState.addNextState(st); +//// currentCompositeState.addTran(lpnTran); +// +// currentCompositeState.nextStateList.add(st); +// currentCompositeState.enabledTranList.add(lpnTran); +// st.incomingStateList.add(currentCompositeState); +// } +// +//// System.out.println(" transList2: " + tranList2.size()); +// for(int i = 0; i < tranList2.size(); i++){ +// LPNTran lpnTran = tranList2.get(i); +// CompositeState nextState = stateList2.get(i); +// State[] nextStateTuple = nextState.getStateTuple(); +// State[] newStateTuple = new State[size]; +// newStateTuple[0] = subState; +// for(int j = 1; j < size; j++){ +// newStateTuple[j] = nextStateTuple[j-1]; +// } +// +// CompositeState newCompositeState = new CompositeState(newStateTuple); +// CompositeState st = compositeSG.addState(newCompositeState); +// if(st == null){ +// newStateStack.push(newCompositeState); +// stateStack.push(subState); +// compositeStateStack.push(nextState); +//// newStateQueue.offer(newCompositeState); +//// stateQueue.offer(subState); +//// compositeStateQueue.offer(nextState); +// +// st = newCompositeState; +// } +// +// // create a new CompositeStateTran +//// CompositeStateTran newCompositeStateTran = new CompositeStateTran(currentCompositeState, st, lpnTran); +//// if(compositeSG.addStateTran(newCompositeStateTran)){ +// // add an edge between the current and new state +//// currentCompositeState.addEdge(newCompositeStateTran); +//// } +// +//// nextStateArray[items] = st; +//// tranArray[items] = lpnTran; +//// items--; +// +//// currentCompositeState.addNextState(st); +//// currentCompositeState.addTran(lpnTran); +// +// currentCompositeState.nextStateList.add(st); +// currentCompositeState.enabledTranList.add(lpnTran); +// st.incomingStateList.add(currentCompositeState); +// } +// +//// System.out.println(" intersect: " + intersect1.size()); +// for(int i = 0; i < intersect1.size(); i++){ +// LPNTran lpnTran = intersectTran.get(i); +// +// State nextState1 = intersect1.get(i); +// CompositeState nextState2 = intersect2.get(i); +// State[] nextStateTuple = nextState2.getStateTuple(); +// +// State[] newStateTuple = new State[size]; +// newStateTuple[0] = nextState1; +// for(int j = 1; j < size; j++){ +// newStateTuple[j] = nextStateTuple[j-1]; +// } +// +// CompositeState newCompositeState = new CompositeState(newStateTuple); +// CompositeState st = compositeSG.addState(newCompositeState); +// if(st == null){ +// newStateStack.push(newCompositeState); +// compositeStateStack.push(nextState2); +// stateStack.push(nextState1); +//// newStateQueue.offer(newCompositeState); +//// stateQueue.offer(nextState1); +//// compositeStateQueue.offer(nextState2); +// +// st = newCompositeState; +// } +// +// // create a new CompositeStateTran +//// CompositeStateTran newCompositeStateTran = new CompositeStateTran(currentCompositeState, st, stTran1.lpnTran); +//// if(compositeSG.addStateTran(newCompositeStateTran)){ +// // add an edge between the current and new state +//// currentCompositeState.addEdge(newCompositeStateTran); +//// } +// +//// nextStateArray[items] = st; +//// tranArray[items] = lpnTran; +//// items--; +// +//// currentCompositeState.addNextState(st); +//// currentCompositeState.addTran(lpnTran); +// +// currentCompositeState.nextStateList.add(st); +// currentCompositeState.enabledTranList.add(lpnTran); +// st.incomingStateList.add(currentCompositeState); +// } +// +//// currentCompositeState.setNextStateArray(nextStateArray); +//// currentCompositeState.setTranArray(tranArray); +// +// long curTotalMem = Runtime.getRuntime().totalMemory(); +// if(curTotalMem > peakTotal) +// peakTotal = curTotalMem; +// +// long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); +// if(curUsedMem > peakUsed) +// peakUsed = curUsedMem; +// } +// +// System.out.println("\n " + compositeSG.getLabel() + ": "); +// System.out.println(" --> # states: " + compositeSG.numCompositeStates()); +//// System.out.println(" --> # transitions: " + compositeSG.numCompositeStateTrans()); +// +// System.out.println(" --> Peak used memory: " + peakUsed/1000000F + " MB"); +// System.out.println(" --> Peak total memory: " + peakTotal/1000000F + " MB"); +// System.out.println(" --> Final used memory: " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1000000F + " MB"); +// +// long elapsedTimeMillis = System.currentTimeMillis()-start; +// float elapsedTimeSec = elapsedTimeMillis/1000F; +// System.out.println(" --> Elapsed time: " + elapsedTimeSec + " sec"); +// +// if(elapsedTimeSec > 60){ +// float elapsedTime = elapsedTimeSec; +// elapsedTime = elapsedTimeSec/(float)60; +// System.out.println(" --> Elapsed time: " + elapsedTime + " min"); +// } +// +// System.out.println(); +// +//// System.out.println(); +//// for(CompositeState cState : compositeSG.compositeStateMap){ +//// State[] stateTuple = cState.getStateTuple(); +//// State s1 = stateTuple[0]; +//// State s2 = stateTuple[1]; +//// +//// System.out.println(s1.getLabel() + ", " + s2.getLabel()); +//// } +// +// return compositeSG; +// } + + public static CompositeStateGraph compose2(CompositeStateGraph sg1, CompositeStateGraph sg2){ + long start = System.currentTimeMillis(); + + if(sg1 == null || sg2 == null){ + return null; + } + + StateGraph[] stateGraphArray1 = sg1.getStateGraphArray(); + StateGraph[] stateGraphArray2 = sg2.getStateGraphArray(); + + // check an output drives an input + boolean compatible = false; + for(StateGraph g : stateGraphArray1){ + for(String output : g.getLpn().getAllOutputs().keySet()){ + for(StateGraph g2 : stateGraphArray2){ + VarSet inputs = (VarSet) g2.getLpn().getAllInputs().keySet(); + if(inputs.contains(output)){ + compatible = true; + break; + } + } + + if(compatible){ + break; + } + } + + if(compatible){ + break; + } + } + + if(!compatible){ + for(StateGraph g1 : stateGraphArray1){ + VarSet inputs = (VarSet) g1.getLpn().getAllInputs().keySet(); + for(StateGraph g2 : stateGraphArray2){ + for(String output : g2.getLpn().getAllOutputs().keySet()){ + if(inputs.contains(output)){ + compatible = true; + break; + } + } + + if(compatible){ + break; + } + } + + if(compatible){ + break; + } + } + } + + if(!compatible){ + System.out.println("state graphs " + sg1.getLabel() + " and " + sg2.getLabel() + " cannot be composed\n"); + return null; + } + + HashSet sgSet = new HashSet(); + for(StateGraph sg : stateGraphArray1){ + if(sgSet.add(sg) == false){ + System.out.println("state graphs " + sg1.getLabel() + " and " + sg2.getLabel() + " cannot be composed\n"); + return null; + } + } + + for(StateGraph sg : stateGraphArray2){ + if(sgSet.add(sg) == false){ + System.out.println("state graphs " + sg1.getLabel() + " and " + sg2.getLabel() + " cannot be composed\n"); + return null; + } + } + + // create new node with init states + int size = sg1.getSize() + sg2.getSize(); + int sg1Size = sg1.getSize(); + int[] initStates = new int[size]; + for(int i = 0; i < sg1Size; i++){ + initStates[i] = stateGraphArray1[i].getInitialState().getIndex(); + } + + for(int i = sg1Size; i < size; i++){ + initStates[i] = stateGraphArray2[i-sg1Size].getInitialState().getIndex(); + } + + CompositeState initNode = new CompositeState(initStates); + + HashSet synchronousTrans = new HashSet(); + //for(StateGraph g1 : stateGraphArray1){ + //LhpnFile lpn1 = g1.getLpn(); + //for(StateGraph g2 : stateGraphArray2){ + //LhpnFile lpn2 = g2.getLpn(); + + // TOOD: Need to use our LPN + /* + HashSet inputTrans = new HashSet(); + inputTrans.addAll(lpn1.getInputTranSet()); + inputTrans.retainAll(lpn2.getOutputTranSet()); + + HashSet outputTrans = new HashSet(); + outputTrans.addAll(lpn2.getInputTranSet()); + outputTrans.retainAll(lpn1.getOutputTranSet()); + + for(LPNTran lpnTran : inputTrans){ + synchronousTrans.add(lpnTran.getIndex()); + } + + for(LPNTran lpnTran : outputTrans){ + synchronousTrans.add(lpnTran.getIndex()); + } + */ + //} + //} + + // create new composite state graph + StateGraph[] sgArray = new StateGraph[size]; + List lpnList = new ArrayList(size); + for(int i = 0; i < sg1Size; i++){ + sgArray[i] = stateGraphArray1[i]; + // TOOD: is this needed??? + //lpnList.add(stateGraphArray1[i].getLpn()); + } + + for(int i = sg1Size; i < size; i++){ + sgArray[i] = stateGraphArray2[i-sg1Size]; + // TOOD: is this needed??? + //lpnList.add(stateGraphArray2[i-sg1Size].getLpn()); + } + + CompositeStateGraph compositeSG = new CompositeStateGraph(initNode, sgArray); + + // create CompositeState stack + Stack newStateStack = new Stack(); + Stack subStateStack1 = new Stack(); + Stack subStateStack2 = new Stack(); + + // initialize with initial CompositionalState + newStateStack.push(initNode); + subStateStack1.push(sg1.getInitState()); + subStateStack2.push(sg2.getInitState()); + + List intersectingTrans1 = new LinkedList(); + List intersectingTrans2 = new LinkedList(); + List independentTrans1 = new LinkedList(); + List independentTrans2 = new LinkedList(); + + long peakUsed = 0; + long peakTotal = 0; + + CompositeState tempState = null; + while(!newStateStack.isEmpty()){ + CompositeState currentState = newStateStack.pop(); + CompositeState subState1 = subStateStack1.pop(); + CompositeState subState2 = subStateStack2.pop(); + + int[] subState1Tuple = subState1.getStateTuple(); + int[] subState2Tuple = subState2.getStateTuple(); + + List stateTrans1 = subState1.getOutgoingStateTranList(); + List stateTrans2 = subState2.getOutgoingStateTranList(); + + // clear reused lists + intersectingTrans1.clear(); + intersectingTrans2.clear(); + independentTrans1.clear(); + independentTrans2.clear(); + + for(CompositeStateTran stateTran : stateTrans1){ + Transition lpnTran = stateTran.getLPNTran(); + + if(!stateTran.visible()){ + independentTrans1.add(stateTran); + } + else{ + if(synchronousTrans.contains(lpnTran.getIndex())){ + for(CompositeStateTran stateTran2 : stateTrans2){ + Transition lpnTran2 = stateTran2.getLPNTran(); + if(lpnTran == lpnTran2){ + intersectingTrans1.add(stateTran); + intersectingTrans2.add(stateTran2); + } + } + } + else{ + independentTrans1.add(stateTran); + } + } + } + + for(CompositeStateTran stateTran : stateTrans2){ + Transition lpnTran = stateTran.getLPNTran(); + + if(!stateTran.visible()){ + independentTrans2.add(stateTran); + } + else{ + if(!synchronousTrans.contains(lpnTran.getIndex())){ + independentTrans2.add(stateTran); + } + } + } + + for(CompositeStateTran stateTran : independentTrans1){ + Transition lpnTran = stateTran.getLPNTran(); + CompositeState nextState = sg1.getState(stateTran.getNextState()); + int[] nextStateTuple = nextState.getStateTuple(); + int[] newStateTuple = new int[size]; + + for(int j = 0; j < sg1Size; j++){ + newStateTuple[j] = nextStateTuple[j]; + } + + for(int j = sg1Size; j < size; j++){ + newStateTuple[j] = subState2Tuple[j-sg1Size]; + } + + CompositeState newCompositeState = new CompositeState(newStateTuple); + tempState = compositeSG.addState(newCompositeState); + if(tempState == newCompositeState){ + newStateStack.push(newCompositeState); + subStateStack1.push(nextState); + subStateStack2.push(subState2); + } + else{ + newCompositeState = tempState; + } + + CompositeStateTran newStateTran = compositeSG.addStateTran(currentState, newCompositeState, lpnTran); + if(!lpnTran.isLocal()){ + newStateTran.setVisibility(); +// System.out.println(newStateTran); + } + } + + for(CompositeStateTran stateTran : independentTrans2){ + Transition lpnTran = stateTran.getLPNTran(); + CompositeState nextState = sg2.getState(stateTran.getNextState()); + int[] nextStateTuple = nextState.getStateTuple(); + int[] newStateTuple = new int[size]; + + for(int i = 0; i < sg1Size; i++){ + newStateTuple[i] = subState1Tuple[i]; + } + + for(int i = sg1Size; i < size; i++){ + newStateTuple[i] = nextStateTuple[i-sg1Size]; + } + + CompositeState newCompositeState = new CompositeState(newStateTuple); + tempState = compositeSG.addState(newCompositeState); + if(tempState == newCompositeState){ + newStateStack.push(newCompositeState); + subStateStack1.push(subState1); + subStateStack2.push(nextState); + } + else{ + newCompositeState = tempState; + } + + CompositeStateTran newStateTran = compositeSG.addStateTran(currentState, newCompositeState, lpnTran); + if(!lpnTran.isLocal()){ + newStateTran.setVisibility(); +// System.out.println(newStateTran); + } + } + + Iterator iter1 = intersectingTrans1.iterator(); + Iterator iter2 = intersectingTrans2.iterator(); + + while(iter1.hasNext()){ + CompositeStateTran stateTran1 = iter1.next(); + CompositeStateTran stateTran2 = iter2.next(); + + Transition lpnTran = stateTran1.getLPNTran(); + CompositeState nextState1 = sg1.getState(stateTran1.getNextState()); + int[] nextState1Tuple = nextState1.getStateTuple(); + CompositeState nextState2 = sg2.getState(stateTran2.getNextState()); + int[] nextState2Tuple = nextState2.getStateTuple(); + int[] newStateTuple = new int[size]; + + for(int i = 0; i < sg1Size; i++){ + newStateTuple[i] = nextState1Tuple[i]; + } + + for(int i = sg1Size; i < size; i++){ + newStateTuple[i] = nextState2Tuple[i-sg1Size]; + } + + CompositeState newCompositeState = new CompositeState(newStateTuple); + tempState = compositeSG.addState(newCompositeState); + if(tempState == newCompositeState){ + newStateStack.push(newCompositeState); + subStateStack1.push(nextState1); + subStateStack2.push(nextState2); + } + else{ + newCompositeState = tempState; + } + + CompositeStateTran newStateTran = compositeSG.addStateTran(currentState, newCompositeState, lpnTran); + if(!lpnList.containsAll(lpnTran.getDstLpnList())){ + newStateTran.setVisibility(); +// System.out.println(newStateTran); + } + } + + long curTotalMem = Runtime.getRuntime().totalMemory(); + if(curTotalMem > peakTotal) + peakTotal = curTotalMem; + + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + if(curUsedMem > peakUsed) + peakUsed = curUsedMem; + + } + + System.out.println("\n " + compositeSG.getLabel() + ": "); + System.out.println(" --> # states: " + compositeSG.numStates()); + System.out.println(" --> # transitions: " + compositeSG.numStateTrans()); + + System.out.println(" --> Peak used memory: " + peakUsed/1000000F + " MB"); + System.out.println(" --> Peak total memory: " + peakTotal/1000000F + " MB"); + System.out.println(" --> Final used memory: " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1000000F + " MB"); + + long elapsedTimeMillis = System.currentTimeMillis()-start; + float elapsedTimeSec = elapsedTimeMillis/1000F; + System.out.println(" --> Elapsed time: " + elapsedTimeSec + " sec"); + + if(elapsedTimeSec > 60){ + float elapsedTime = elapsedTimeSec; + elapsedTime = elapsedTimeSec/60; + System.out.println(" --> Elapsed time: " + elapsedTime + " min"); + } + + System.out.println(); + + return compositeSG; + } + + public static CompositeStateGraph compose(CompositeStateGraph sg1, CompositeStateGraph sg2){ + long start = System.currentTimeMillis(); + + if(sg1 == null || sg2 == null){ + return null; + } + + StateGraph[] stateGraphArray1 = sg1.getStateGraphArray(); + StateGraph[] stateGraphArray2 = sg2.getStateGraphArray(); + + // check an output drives an input + boolean compatible = false; + for(StateGraph g : stateGraphArray1){ + for(String output : g.getLpn().getAllOutputs().keySet()){ + for(StateGraph g2 : stateGraphArray2){ + VarSet inputs = (VarSet) g2.getLpn().getAllInputs().keySet(); + if(inputs.contains(output)){ + compatible = true; + break; + } + } + + if(compatible){ + break; + } + } + + if(compatible){ + break; + } + } + + if(!compatible){ + for(StateGraph g1 : stateGraphArray1){ + VarSet inputs = (VarSet) g1.getLpn().getAllInputs().keySet(); + for(StateGraph g2 : stateGraphArray2){ + for(String output : g2.getLpn().getAllOutputs().keySet()){ + if(inputs.contains(output)){ + compatible = true; + break; + } + } + + if(compatible){ + break; + } + } + + if(compatible){ + break; + } + } + } + + if(!compatible){ + System.out.println("state graphs " + sg1.getLabel() + " and " + sg2.getLabel() + " cannot be composed\n"); + return null; + } + + HashSet sgSet = new HashSet(); + for(StateGraph sg : stateGraphArray1){ + if(sgSet.add(sg) == false){ + System.out.println("state graphs " + sg1.getLabel() + " and " + sg2.getLabel() + " cannot be composed\n"); + return null; + } + } + + for(StateGraph sg : stateGraphArray2){ + if(sgSet.add(sg) == false){ + System.out.println("state graphs " + sg1.getLabel() + " and " + sg2.getLabel() + " cannot be composed\n"); + return null; + } + } + + // create new node with init states + int size = sg1.getSize() + sg2.getSize(); + int sg1Size = sg1.getSize(); + int[] initStates = new int[size]; + for(int i = 0; i < sg1Size; i++){ + initStates[i] = stateGraphArray1[i].getInitialState().getIndex(); + } + + for(int i = sg1Size; i < size; i++){ + initStates[i] = stateGraphArray2[i-sg1Size].getInitialState().getIndex(); + } + + CompositeState initNode = new CompositeState(initStates); + + HashSet synchronousTrans = new HashSet(); + //for(StateGraph g1 : stateGraphArray1){ + //LhpnFile lpn1 = g1.getLpn(); + //for(StateGraph g2 : stateGraphArray2){ + //LhpnFile lpn2 = g2.getLpn(); + // TOOD: need to change to use our LPN + /* + HashSet inputTrans = new HashSet(); + inputTrans.addAll(lpn1.getInputTranSet()); + inputTrans.retainAll(lpn2.getOutputTranSet()); + + HashSet outputTrans = new HashSet(); + outputTrans.addAll(lpn2.getInputTranSet()); + outputTrans.retainAll(lpn1.getOutputTranSet()); + + synchronousTrans.addAll(inputTrans); + synchronousTrans.addAll(outputTrans); + */ + //} + //} + + // create new composite state graph + StateGraph[] sgArray = new StateGraph[size]; + List lpnList = new ArrayList(size); + for(int i = 0; i < sg1Size; i++){ + sgArray[i] = stateGraphArray1[i]; + // TODO: (future) Is this needed?? + //lpnList.add(stateGraphArray1[i].getLpn()); + } + + for(int i = sg1Size; i < size; i++){ + sgArray[i] = stateGraphArray2[i-sg1Size]; + // TODO: (future) Is this needed?? + //lpnList.add(stateGraphArray2[i-sg1Size].getLpn()); + } + + CompositeStateGraph compositeSG = new CompositeStateGraph(initNode, sgArray); + + // create CompositeState stack + Stack newStateStack = new Stack(); + Stack subStateStack1 = new Stack(); + Stack subStateStack2 = new Stack(); + + // initialize with initial CompositionalState + newStateStack.push(initNode); + subStateStack1.push(sg1.getInitState()); + subStateStack2.push(sg2.getInitState()); + + List intersectingTrans = new ArrayList(); + List intStateList1 = new ArrayList(); + List intStateList2 = new ArrayList(); + List independentTrans1 = new ArrayList(); + List indStateList1 = new ArrayList(); + List independentTrans2 = new ArrayList(); + List indStateList2 = new ArrayList(); + + long peakUsed = 0; + long peakTotal = 0; + + CompositeState tempState = null; + while(!newStateStack.isEmpty()){ + CompositeState currentState = newStateStack.pop(); + CompositeState subState1 = subStateStack1.pop(); + CompositeState subState2 = subStateStack2.pop(); + + int[] subState1Tuple = subState1.getStateTuple(); + int[] subState2Tuple = subState2.getStateTuple(); + + List stateTrans1 = subState1.getOutgoingStateTranList(); + List stateTrans2 = subState2.getOutgoingStateTranList(); + + // clear reused lists + intersectingTrans.clear(); + intStateList1.clear(); + intStateList2.clear(); + independentTrans1.clear(); + indStateList1.clear(); + independentTrans2.clear(); + indStateList2.clear(); + + for(CompositeStateTran stateTran : stateTrans1){ + Transition lpnTran = stateTran.getLPNTran(); + CompositeState nextState = sg1.getState(stateTran.getNextState()); + + if(!stateTran.visible()){ + independentTrans1.add(lpnTran); + indStateList1.add(nextState); + } + else{ + if(synchronousTrans.contains(lpnTran)){ + for(CompositeStateTran stateTran2 : stateTrans2){ + Transition lpnTran2 = stateTran2.getLPNTran(); + CompositeState nextState2 = sg2.getState(stateTran2.getNextState()); + if(lpnTran == lpnTran2){ + intersectingTrans.add(lpnTran); + intStateList1.add(nextState); + intStateList2.add(nextState2); + } + } + } + else{ + independentTrans1.add(lpnTran); + indStateList1.add(nextState); + } + } + } + + for(CompositeStateTran stateTran : stateTrans2){ + Transition lpnTran = stateTran.getLPNTran(); + CompositeState nextState = sg2.getState(stateTran.getNextState()); + + if(!stateTran.visible()){ + independentTrans2.add(lpnTran); + indStateList2.add(nextState); + } + else{ + if(!synchronousTrans.contains(lpnTran)){ + independentTrans2.add(lpnTran); + indStateList2.add(nextState); + } + } + } + + for(int i = 0; i < independentTrans1.size(); i++){ + Transition lpnTran = independentTrans1.get(i); + CompositeState nextState = indStateList1.get(i); + int[] nextStateTuple = nextState.getStateTuple(); + int[] newStateTuple = new int[size]; + + for(int j = 0; j < sg1Size; j++){ + newStateTuple[j] = nextStateTuple[j]; + } + + for(int j = sg1Size; j < size; j++){ + newStateTuple[j] = subState2Tuple[j-sg1Size]; + } + + CompositeState newCompositeState = new CompositeState(newStateTuple); + tempState = compositeSG.addState(newCompositeState); + if(tempState == newCompositeState){ + newStateStack.push(newCompositeState); + subStateStack1.push(nextState); + subStateStack2.push(subState2); + } + else{ + newCompositeState = tempState; + } + + CompositeStateTran newStateTran = compositeSG.addStateTran(currentState, newCompositeState, lpnTran); + if(!lpnTran.isLocal()){ + newStateTran.setVisibility(); +// System.out.println(newStateTran); + } + } + + for(int j = 0; j < independentTrans2.size(); j++){ + Transition lpnTran = independentTrans2.get(j); + CompositeState nextState = indStateList2.get(j); + int[] nextStateTuple = nextState.getStateTuple(); + int[] newStateTuple = new int[size]; + + for(int i = 0; i < sg1Size; i++){ + newStateTuple[i] = subState1Tuple[i]; + } + + for(int i = sg1Size; i < size; i++){ + newStateTuple[i] = nextStateTuple[i-sg1Size]; + } + + CompositeState newCompositeState = new CompositeState(newStateTuple); + tempState = compositeSG.addState(newCompositeState); + if(tempState == newCompositeState){ + newStateStack.push(newCompositeState); + subStateStack1.push(subState1); + subStateStack2.push(nextState); + } + else{ + newCompositeState = tempState; + } + + CompositeStateTran newStateTran = compositeSG.addStateTran(currentState, newCompositeState, lpnTran); + if(!lpnTran.isLocal()){ + newStateTran.setVisibility(); +// System.out.println(newStateTran); + } + } + + for(int j = 0; j < intersectingTrans.size(); j++){ + Transition lpnTran = intersectingTrans.get(j); + CompositeState nextState1 = intStateList1.get(j); + int[] nextState1Tuple = nextState1.getStateTuple(); + CompositeState nextState2 = intStateList2.get(j); + int[] nextState2Tuple = nextState2.getStateTuple(); + int[] newStateTuple = new int[size]; + + for(int i = 0; i < sg1Size; i++){ + newStateTuple[i] = nextState1Tuple[i]; + } + + for(int i = sg1Size; i < size; i++){ + newStateTuple[i] = nextState2Tuple[i-sg1Size]; + } + + CompositeState newCompositeState = new CompositeState(newStateTuple); + tempState = compositeSG.addState(newCompositeState); + if(tempState == newCompositeState){ + newStateStack.push(newCompositeState); + subStateStack1.push(nextState1); + subStateStack2.push(nextState2); + } + else{ + newCompositeState = tempState; + } + + CompositeStateTran newStateTran = compositeSG.addStateTran(currentState, newCompositeState, lpnTran); + if(!lpnList.containsAll(lpnTran.getDstLpnList())){ + newStateTran.setVisibility(); +// System.out.println(newStateTran); + } + } + + long curTotalMem = Runtime.getRuntime().totalMemory(); + if(curTotalMem > peakTotal) + peakTotal = curTotalMem; + + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + if(curUsedMem > peakUsed) + peakUsed = curUsedMem; + + } + + System.out.println("\n " + compositeSG.getLabel() + ": "); + System.out.println(" --> # states: " + compositeSG.numStates()); + System.out.println(" --> # transitions: " + compositeSG.numStateTrans()); + + System.out.println(" --> Peak used memory: " + peakUsed/1000000F + " MB"); + System.out.println(" --> Peak total memory: " + peakTotal/1000000F + " MB"); + System.out.println(" --> Final used memory: " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1000000F + " MB"); + + long elapsedTimeMillis = System.currentTimeMillis()-start; + float elapsedTimeSec = elapsedTimeMillis/1000F; + System.out.println(" --> Elapsed time: " + elapsedTimeSec + " sec"); + + if(elapsedTimeSec > 60){ + float elapsedTime = elapsedTimeSec; + elapsedTime = elapsedTimeSec/60; + System.out.println(" --> Elapsed time: " + elapsedTime + " min"); + } + + System.out.println(); + + return compositeSG; + } + + public void compositionalAnalsysis(List designUnitSet) { +// System.out.println("\n****** Compositional Analysis ******"); +// long start = System.currentTimeMillis(); +// +// if(Options.getParallelFlag()){ +// parallelCompositionalFindSG(designUnitSet); +// } +// else{ +// compositionalFindSG(designUnitSet); +// } + + findReducedSG(designUnitSet); + +// long totalMillis = System.currentTimeMillis()-start; +// float totalSec = totalMillis/1000F; +// System.out.println("\n***** Total Elapsed Time: " + totalSec + " sec *****"); +// +// if(totalSec > 60){ +// float totalTime = totalSec/(float)60; +// System.out.println("***** Total Elapsed Time: " + totalTime + " min *****"); +// } +// +// System.out.println(); + } + + public void findReducedSG(List designUnitSet) { + System.out.println("\n****** Compositional Analysis ******"); + long start = System.currentTimeMillis(); + + StateGraph[] sgArray = (StateGraph[]) designUnitSet.toArray(); + compositionalFindSG(sgArray); + + List sgList = new ArrayList(); + System.out.println(); + + long peakTotal = 0; + long peakUsed = 0; + int largestSG = 0; + + for(StateGraph sg : designUnitSet){ + CompositeStateGraph csg = new CompositeStateGraph(sg); + if(csg.numStates() > largestSG){ + largestSG = csg.numStates(); + } + +// csg.draw(); + if(Options.getCompositionalMinimization().equals("reduction")){ +// reduce(csg); + } + else if(Options.getCompositionalMinimization().equals("abstraction")){ + System.out.println(csg.getLabel() + ": transitionBasedAbstraction"); + transitionBasedAbstraction(csg); +// csg.draw(); + System.out.println(csg.getLabel() + ": mergeOutgoing"); + mergeOutgoing(csg); +// csg.draw(); + System.out.println(csg.getLabel() + ": mergeIncoming"); + mergeIncoming(csg); + System.out.println(); + +// csg.draw(); + } + + if(csg.numStates() > largestSG){ + largestSG = csg.numStates(); + } + + sgList.add(csg); + + long curTotalMem = Runtime.getRuntime().totalMemory(); + if(curTotalMem > peakTotal) + peakTotal = curTotalMem; + + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + if(curUsedMem > peakUsed) + peakUsed = curUsedMem; + } + + CompositeStateGraph csg = null; + if(sgList.size() > 0){ + csg = sgList.get(0); + sgList.remove(0); + } + + while(csg != null && sgList.size() > 1){ + CompositeStateGraph tmpSG = null; + + for(CompositeStateGraph sg2 : sgList){ + tmpSG = compose(csg, sg2); + + if(csg.numStates() > largestSG){ + largestSG = csg.numStates(); + } + + if(tmpSG != null){ + sgList.remove(sg2); +// tmpSG.draw(); + System.out.println(); + if(Options.getCompositionalMinimization().equals("reduction")){ +// reduce(tmpSG); + } + else if(Options.getCompositionalMinimization().equals("abstraction")){ + System.out.println(tmpSG.getLabel() + ": transitionBasedAbstraction"); + transitionBasedAbstraction(tmpSG); +// tmpSG.draw(); + System.out.println(tmpSG.getLabel() + ": mergeOutgoing"); + mergeOutgoing(tmpSG); +// tmpSG.draw(); + System.out.println(tmpSG.getLabel() + ": mergeIncoming"); + mergeIncoming(tmpSG); + System.out.println(); + +// tmpSG.draw(); + } + + if(csg.numStates() > largestSG){ + largestSG = csg.numStates(); + } + + break; + } + } + + csg = tmpSG; + + long curTotalMem = Runtime.getRuntime().totalMemory(); + if(curTotalMem > peakTotal) + peakTotal = curTotalMem; + + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + if(curUsedMem > peakUsed) + peakUsed = curUsedMem; + } + + if(sgList.size() == 1){ + csg = compose(csg, sgList.get(0)); + + if(csg.numStates() > largestSG){ + largestSG = csg.numStates(); + } + + long curTotalMem = Runtime.getRuntime().totalMemory(); + if(curTotalMem > peakTotal) + peakTotal = curTotalMem; + + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + if(curUsedMem > peakUsed) + peakUsed = curUsedMem; + } + +// csg.draw(); + + long curTotalMem = Runtime.getRuntime().totalMemory(); + if(curTotalMem > peakTotal) + peakTotal = curTotalMem; + + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + if(curUsedMem > peakUsed) + peakUsed = curUsedMem; + + long totalMillis = System.currentTimeMillis()-start; + float totalSec = totalMillis/1000F; + System.out.println("\n****** Total Elapsed Time: " + totalSec + " sec ******"); + + if(totalSec > 60){ + float totalTime = totalSec/60; + System.out.println("****** Total Elapsed Time: " + totalTime + " min ******"); + } + + System.out.println("****** Peak Memory Used: " + peakUsed/1000000F + " MB ******"); + System.out.println("****** Peak Memory Total: " + peakTotal/1000000F + " MB ******"); + System.out.println("****** Lastest SG: " + largestSG + " states ******"); + System.out.println(); + } + +// public void reduce(CompositeStateGraph sg){ +// long startTime = System.currentTimeMillis(); +// int initNumTrans = sg.numTransitions; +// int initNumStates = sg.compositeStateMap.size(); +// int totalReducedTrans = sg.numTransitions; +// +// int case2StateMin = 0; +// int case3StateMin = 0; +// int case2TranMin = 0; +// int case3TranMin = 0; +// +// int iter = 0; +// while(totalReducedTrans > 0){ +// totalReducedTrans = 0; +// +// int numStates = sg.compositeStateMap.size(); +// int numTrans = sg.numTransitions; +// int tranDiff = 0; +// +// case2(sg); +// +// case2TranMin += numTrans - sg.numTransitions; +// tranDiff = numStates - sg.compositeStateMap.size(); +// case2StateMin += tranDiff; +// totalReducedTrans += tranDiff; +// +// numTrans = sg.numTransitions; +// numStates = sg.compositeStateMap.size(); +// +// case3(sg); +// +// case3TranMin += numTrans - sg.numTransitions; +// tranDiff = numStates - sg.compositeStateMap.size(); +// case3StateMin += tranDiff; +// totalReducedTrans += tranDiff; +// +// iter++; +// } +// +// System.out.println(" Reduce " + sg.getLabel() + ": "); +// System.out.println(" --> case2: -" + case2StateMin + " states"); +// System.out.println(" --> case2: -" + case2TranMin + " transitions"); +// System.out.println(" --> case3: -" + case3StateMin + " states"); +// System.out.println(" --> case3: -" + case3TranMin + " transitions"); +// System.out.println(" --> # states: " + sg.compositeStateMap.size()); +// System.out.println(" --> # transitions: " + sg.numTransitions); +// System.out.println(" --> # iterations: " + iter); +// long elapsedTimeMillis = System.currentTimeMillis()-startTime; +// float elapsedTimeSec = elapsedTimeMillis/1000F; +// System.out.println(" --> Elapsed time: " + elapsedTimeSec + " sec\n"); +// } + + public static void transitionBasedAbstraction(CompositeStateGraph sg){ + HashSet stateSet = new HashSet(); + HashSet tranSet = new HashSet(); + CompositeState initialState = sg.getInitState(); + + Stack stateTranStack = new Stack(); + HashSet loopSet = new HashSet(); // set used to detect loops + HashSet traversalSet = new HashSet(); // set used to avoid duplicate work + +// int count = 0; + for(CompositeStateTran nonlocalStateTran : sg.getStateTranSet()){ +// count++; +// System.out.println(count + "/" + sg.getStateTranSet().size()); +// if(!sg.containsStateTran(nonlocalStateTran)) continue; + + Transition lpnTran = nonlocalStateTran.getLPNTran(); + if(!nonlocalStateTran.visible()){ + continue; + } + else if(nonlocalStateTran.getNextState() == sg.getInitState().getIndex()){ + // add current state transition + tranSet.add(nonlocalStateTran); + stateSet.add(nonlocalStateTran.getCurrentState()); + stateSet.add(nonlocalStateTran.getNextState()); + continue; + } + + // state transition stack for dfs traversal + stateTranStack.clear(); + + // set used to detect loops + loopSet.clear(); + loopSet.add(nonlocalStateTran.getNextState()); + + // set used to avoid duplicate work + traversalSet.clear(); + traversalSet.add(nonlocalStateTran.getNextState()); + + boolean flag = false; + CompositeState nextState = sg.getState(nonlocalStateTran.getNextState()); + for(CompositeStateTran outgoingTran : nextState.getOutgoingStateTranList()){ + if(!outgoingTran.visible()){ + stateTranStack.push(outgoingTran); + loopSet.add(outgoingTran.getNextState()); +// traversalSet.add(outgoingTran.getNextState()); + } + else{ + flag = true; + } + } + + // keep nonlocal state transition if a visible successor state transition exists + if(flag){ + tranSet.add(nonlocalStateTran); + stateSet.add(nonlocalStateTran.getCurrentState()); + stateSet.add(nonlocalStateTran.getNextState()); + } + +// System.out.println(nonlocalStateTran); + while(!stateTranStack.empty()){ + CompositeStateTran currentStateTran = stateTranStack.pop(); + CompositeState currentNextState = sg.getState(currentStateTran.getNextState()); + +// // if state has already been encountered skip + if(!traversalSet.add(currentStateTran.getNextState())){ +// System.out.println(" " + currentStateTran); +// System.out.println("skip"); + continue; + } + + if(currentNextState == initialState){ + CompositeStateTran newStateTran = new CompositeStateTran(nonlocalStateTran.getCurrentState(), + currentStateTran.getNextState(), lpnTran); + + System.out.println(newStateTran.getCurrentState() + " -> " + newStateTran.getNextState()); + newStateTran.setVisibility(); + tranSet.add(newStateTran); + stateSet.add(newStateTran.getCurrentState()); + stateSet.add(newStateTran.getCurrentState()); + + continue; + } + + // if the state transition does not have successor transitions create a state transition to last state in path + if(currentNextState.numOutgoingTrans() == 0){ + CompositeStateTran newStateTran = new CompositeStateTran(nonlocalStateTran.getCurrentState(), + currentStateTran.getNextState(), lpnTran); + + newStateTran.setVisibility(); + tranSet.add(newStateTran); + stateSet.add(newStateTran.getCurrentState()); + stateSet.add(newStateTran.getNextState()); + } + + // add local outgoing state trans to stack + // for each nonlocal state tran create a state transition from nonlocalStateTran.currentState to stateTran.currentState + for(CompositeStateTran stateTran : currentNextState.getOutgoingStateTranList()){ + if(stateTran.visible()){ + CompositeStateTran newStateTran = new CompositeStateTran(nonlocalStateTran.getCurrentState(), + stateTran.getCurrentState(), lpnTran); + + newStateTran.setVisibility(); + tranSet.add(newStateTran); + stateSet.add(nonlocalStateTran.getCurrentState()); + stateSet.add(stateTran.getCurrentState()); + } + else{ +// if(!loopSet.add(stateTran.getNextState())){ +// // create self loop after visible state transition +// if(flag){ +// CompositeStateTran newStateTran = new CompositeStateTran(nonlocalStateTran.getNextState(), +// nonlocalStateTran.getNextState(), currentStateTran.getLPNTran()); +// +// tranSet.add(newStateTran); +// } +// else{ +// tranSet.add(nonlocalStateTran); +// stateSet.add(nonlocalStateTran.getCurrentState()); +// stateSet.add(nonlocalStateTran.getNextState()); +// flag = true; +// +// CompositeStateTran newStateTran = new CompositeStateTran(nonlocalStateTran.getNextState(), +// nonlocalStateTran.getNextState(), currentStateTran.getLPNTran()); +// +// tranSet.add(newStateTran); +// } +// +//// traversalSet.add(stateTran.getNextState()); +// continue; +// } +// else if(!traversalSet.add(stateTran.getNextState())){ +// continue; +// } + + stateTranStack.push(stateTran); + } + } + + loopSet.remove(currentNextState.getIndex()); + } + } + + System.out.println(stateSet.size()); + System.out.println(tranSet.size()); +// System.out.println("INITIAL STATE"); + // handle initial state + loopSet.clear(); + loopSet.add(initialState.getIndex()); + + traversalSet.clear(); + traversalSet.add(initialState.getIndex()); + + for(CompositeStateTran stateTran : initialState.getOutgoingStateTranList()){ + if(!stateTran.visible()){ + stateTranStack.push(stateTran); + loopSet.add(stateTran.getNextState()); +// traversalSet.add(stateTran.getNextState()); + } + } + + stateSet.add(initialState.getIndex()); + + while(!stateTranStack.empty()){ + CompositeStateTran stateTran = stateTranStack.pop(); + +// // if state has already been encountered skip + if(!traversalSet.add(stateTran.getNextState())){ + continue; + } + + CompositeState nextState = sg.getState(stateTran.getNextState()); + + // if the state transition does not have successor transitions create a state transition to last state in path + if(nextState.numOutgoingTrans() == 0){ + CompositeStateTran newStateTran = new CompositeStateTran(initialState, sg.getState(stateTran.getNextState()), + stateTran.getLPNTran()); + + newStateTran.setVisibility(); + tranSet.add(newStateTran); + stateSet.add(stateTran.getNextState()); + } + + for(CompositeStateTran succStateTran : nextState.getOutgoingStateTranList()){ + Transition lpnTran = succStateTran.getLPNTran(); + + if(succStateTran.visible()){ + // create a state tran from initial state to succStateTran.currentState + CompositeStateTran newStateTran = new CompositeStateTran(initialState, sg.getState(succStateTran.getNextState()), lpnTran); + newStateTran.setVisibility(); + tranSet.add(newStateTran); + stateSet.add(succStateTran.getNextState()); + } + else{ +// if(!loopSet.add(succStateTran.getNextState())){ +// CompositeStateTran newStateTran = new CompositeStateTran(initialState, initialState, lpnTran); +// tranSet.add(newStateTran); +// +//// traversalSet.add(succStateTran.getNextState()); +// continue; +// } +// else if(!traversalSet.add(succStateTran.getNextState())){ +// continue; +// } + + // add to stack + stateTranStack.push(succStateTran); + } + } + + loopSet.remove(stateTran.getNextState()); + } + +// System.out.println(); +// for(CompositeStateTran stateTran : tranSet){ +// System.out.println(stateTran); +// } +// System.out.println(); +// +// System.out.println(); +// for(Integer state : stateSet){ +// System.out.println(state); +// } +// System.out.println(); + +// System.out.println("COMPOSITE STATE SET"); + HashMap stateMap = new HashMap(); + HashMap indexStateMap = new HashMap(); + for(Integer stateIndex : stateSet){ + CompositeState currentState = sg.getState(stateIndex); + currentState.clear(); + + stateMap.put(currentState, currentState); + indexStateMap.put(stateIndex, currentState); + } + + sg.indexStateMap = indexStateMap; + sg.stateMap = stateMap; + + sg.stateTranMap = new HashMap(); + for(CompositeStateTran stateTran : tranSet){ + sg.addStateTran(stateTran); + } + + System.out.println(" --> # states: " + stateSet.size()); + System.out.println(" --> # transitions: " + tranSet.size()); + } + + private void removeUnreachableState(CompositeStateGraph sg, CompositeState currentState){ + if(currentState == sg.getInitState()){ + return; + } + else if(currentState.numIncomingTrans() != 0){ + return; + } + + boolean rc = sg.containsState(currentState.getIndex()); + if(rc == false){ + return; + } + + for(CompositeStateTran stateTran : currentState.getOutgoingStateTranList().toArray(new CompositeStateTran[currentState.numOutgoingTrans()])){ + sg.removeStateTran(stateTran); + + CompositeState nextState = sg.getState(stateTran.getNextState()); + if(nextState.numIncomingTrans() == 0){ + removeUnreachableState(sg, nextState); + } + } + + sg.removeState(currentState); + } + + private void removeDanglingState(CompositeStateGraph sg, CompositeState currentState){ + if(currentState == sg.getInitState()){ + return; + } + else if(currentState.numOutgoingTrans() != 0){ + return; + } + + boolean rc = sg.containsState(currentState.getIndex()); + if(rc == false){ + return; + } + + for(CompositeStateTran stateTran : currentState.getIncomingStateTranList().toArray(new CompositeStateTran[currentState.numIncomingTrans()])){ + sg.removeStateTran(stateTran); + + CompositeState previousState = sg.getState(stateTran.getCurrentState()); + if(previousState.numOutgoingTrans() == 0){ + removeDanglingState(sg, previousState); + } + } + + sg.removeState(currentState); + } + + public void redundantStateRemoval(CompositeStateGraph sg){ + this.mergeOutgoing(sg); + this.mergeIncoming(sg); + } + + public void mergeOutgoing(CompositeStateGraph sg){ +// System.out.println("FIND EQUIVALENT PAIRS"); + HashSet> equivalentPairSet = findInitialEquivalentPairs(sg); +// System.out.println("REMOVE STATES"); + // remove states that are not equivalent + for(Pair eqPair : equivalentPairSet.toArray(new Pair[equivalentPairSet.size()])){ + CompositeState state1 = sg.getState(eqPair.getLeft()); + CompositeState state2 = sg.getState(eqPair.getRight()); + + List stateTranList1 = state1.getOutgoingStateTranList(); + List stateTranList2 = state2.getOutgoingStateTranList(); + + boolean eq = true; + for(CompositeStateTran stateTran1 : stateTranList1){ + boolean succEq = false; + for(CompositeStateTran stateTran2 : stateTranList2){ + int nextState1 = stateTran1.getNextState(); + int nextState2 = stateTran2.getNextState(); + + if(nextState1 == nextState2){ + succEq = true; + continue; + } + + if(nextState2 < nextState1){ + int tmp = nextState2; + nextState2 = nextState1; + nextState1 = tmp; + } + + Pair statePair = new Pair(nextState1, nextState2); + if(equivalentPairSet.contains(statePair)){ + succEq = true; + continue; + } + } + + if(!succEq){ + eq = false; + break; + } + } + + if(!eq){ + equivalentPairSet.remove(eqPair); + } + } + + for(Pair statePair : equivalentPairSet){ + int stateIndex1 = statePair.getLeft(); + int stateIndex2 = statePair.getRight(); + + if(!sg.containsState(stateIndex1) || !sg.containsState(stateIndex2)) + continue; + + System.out.println(stateIndex1 + " - " + stateIndex2); + CompositeState state2 = sg.getState(stateIndex2); + + // merge + for(CompositeStateTran incomingStateTran : state2.getIncomingStateTranList().toArray(new CompositeStateTran[state2.numIncomingTrans()])){ + sg.removeStateTran(incomingStateTran); + + incomingStateTran.setNextState(stateIndex1); + sg.addStateTran(incomingStateTran); + } + + this.removeUnreachableState(sg, state2); + } + + System.out.println(" --> # states: " + sg.numStates()); + System.out.println(" --> # transitions: " + sg.numStateTrans()); + } + + public void mergeIncoming(CompositeStateGraph sg){ + HashSet> equivalentPairSet = findInitialEquivalentPairs2(sg); + + for(Pair statePair : equivalentPairSet){ + int stateIndex1 = statePair.getLeft(); + int stateIndex2 = statePair.getRight(); + + System.out.println(stateIndex1 + " - " + stateIndex2); + + if(!sg.containsState(stateIndex1) || !sg.containsState(stateIndex2)) + continue; + + CompositeState state2 = sg.getState(stateIndex2); + + // merge outgoing state transitions + for(CompositeStateTran outgoingStateTran : state2.getOutgoingStateTranList().toArray(new CompositeStateTran[state2.numOutgoingTrans()])){ + sg.removeStateTran(outgoingStateTran); + + outgoingStateTran.setCurrentState(stateIndex1); + sg.addStateTran(outgoingStateTran); + } + + this.removeDanglingState(sg, state2); + } + + System.out.println(" --> # states: " + sg.numStates()); + System.out.println(" --> # transitions: " + sg.numStateTrans()); + } + + private static HashSet> findInitialEquivalentPairs(CompositeStateGraph sg){ + HashSet> equivalentSet = new HashSet>(); + CompositeState[] stateArray = sg.getStateSet().toArray(new CompositeState[sg.numStates()]); + + for(int i = 0; i < stateArray.length; i++){ +// System.out.println(" " + i + "/" + stateArray.length); + CompositeState state1 = stateArray[i]; + List enabled1 = CompositeStateGraph.getEnabled(state1); +// HashSet enabled1Set = new HashSet(); +// enabled1Set.addAll(enabled1); + + for(int j = i + 1; j < stateArray.length; j++){ +// System.out.println(" " + j + "/" + stateArray.length); + CompositeState state2 = stateArray[j]; + CompositeState state = state1; + + List enabled2 = CompositeStateGraph.getEnabled(state2); + + if(enabled1.containsAll(enabled2) && enabled2.containsAll(enabled1)){ + if(state2.getIndex() < state.getIndex()){ + CompositeState temp = state; + state = state2; + state2 = temp; + } + + equivalentSet.add(new Pair(state.getIndex(), state2.getIndex())); + } + } + } + + return equivalentSet; + } + + @SuppressWarnings("unused") + private static boolean equivalentOutgoing(Set enabled1, List enabled2){ +// enabled2.containsAll(enabled1) && enabled1.containsAll(enabled2) + HashSet enabled2Set = new HashSet(); + enabled2Set.addAll(enabled2); + + if(enabled2Set.size() == enabled1.size() && enabled1.containsAll(enabled2Set)) + return true; + + return false; + } + + private static HashSet> findInitialEquivalentPairs2(CompositeStateGraph sg){ + HashSet> equivalentSet = new HashSet>(); + + CompositeState[] stateArray = sg.getStateSet().toArray(new CompositeState[sg.numStates()]); + for(int i = 0; i < stateArray.length; i++){ + CompositeState state1 = stateArray[i]; + List enabled1 = CompositionalAnalysis.getIncomingLpnTrans(state1); + + for(int j = i + 1; j < stateArray.length; j++){ + CompositeState state2 = stateArray[j]; + CompositeState state = state1; + + List enabled2 = CompositionalAnalysis.getIncomingLpnTrans(state2); + + if(enabled2.containsAll(enabled1) && enabled1.containsAll(enabled2)){ + if(state2.getIndex() < state.getIndex()){ + CompositeState temp = state; + state = state2; + state2 = temp; + } + + equivalentSet.add(new Pair(state.getIndex(), state2.getIndex())); + } + } + } + + return equivalentSet; + } + + private static List getIncomingLpnTrans(CompositeState currentState){ + Set lpnTranSet = new HashSet(currentState.numOutgoingTrans()); + List enabled = new ArrayList(currentState.numOutgoingTrans()); + + for(CompositeStateTran stTran : currentState.getIncomingStateTranList()){ + Transition lpnTran = stTran.getLPNTran(); + if(lpnTranSet.add(lpnTran)) + enabled.add(lpnTran); + } + + return enabled; + } +// public void case2(CompositeStateGraph sg){ +// long start = System.currentTimeMillis(); +// int trans = sg.numTransitions; +// int states = sg.numCompositeStates(); +// +// List localTrans = new ArrayList(); +// List localStates = new ArrayList(); +// List nonLocalTrans = new ArrayList(); +// List nonLocalStates = new ArrayList(); +// +// for(Object o : sg.getStateMap().values().toArray()){ +// CompositeState currentState = (CompositeState) o; +// +// List enabledTrans = currentState.enabledTranList; +// List nextStates = currentState.nextStateList; +// +// localTrans.clear(); +// localStates.clear(); +// nonLocalTrans.clear(); +// nonLocalStates.clear(); +// +// for(int i = 0; i < enabledTrans.size(); i++){ +// LPNTran lpnTran = enabledTrans.get(i); +// CompositeState nextState = (nextStates.get(i)); +// if(lpnTran.local()){ +// localTrans.add(lpnTran); +// localStates.add(nextState); +// } +//// else{ +// nonLocalTrans.add(lpnTran); +// nonLocalStates.add(nextState); +//// } +// } +// +// if(nonLocalTrans.isEmpty()){ +// continue; +// } +// +// for(int i = 0; i < nonLocalTrans.size(); i++){ +// LPNTran nonLocalTran = nonLocalTrans.get(i); +// CompositeState s2 = nonLocalStates.get(i); +// +// List s2Enabled = s2.enabledTranList; +// if(s2Enabled.size() > 1 || s2Enabled.size() < 1){ +// continue; +// } +//// else if(s2 == sg.getInitState()){ +//// continue; +//// } +// +// List s2NextState = s2.nextStateList; +// for(int j = 0; j < s2Enabled.size(); j++){ +// LPNTran invTran2 = s2Enabled.get(j); +// if(invTran2.local()){ +// CompositeState s4 = s2NextState.get(j); +// +// for(int k = 0; k < localTrans.size(); k++){ +// LPNTran invTran = localTrans.get(k); +// if(invTran == nonLocalTran) continue; +// +// CompositeState s3 = localStates.get(k); +// +// List s3Enabled = s3.enabledTranList; +// List s3NextState = s3.nextStateList; +// for(int n = 0; n < s3Enabled.size(); n++){ +// LPNTran nonLocalTran2 = s3Enabled.get(n); +// CompositeState nextState = s3NextState.get(n); +// +// if(nonLocalTran2 == nonLocalTran && nextState == s4){ +// currentState.enabledTranList.remove(nonLocalTran); +// currentState.nextStateList.remove(s2); +// sg.numTransitions --; +// +// List incomingStates = s2.incomingStateList; +// for(int m = 0; m < incomingStates.size(); m++){ +// CompositeState curr = incomingStates.get(m); +// List incomingNextStateList = curr.nextStateList; +// +// for(int idx = 0; idx < incomingNextStateList.size(); idx++){ +// CompositeState tmpState = incomingNextStateList.get(idx); +// if(tmpState == s2){ +// incomingNextStateList.set(idx, s4); +// s4.incomingStateList.add(curr); +// break; +// } +// } +// } +// +// s2.nextStateList.clear(); +// s2.incomingStateList.clear(); +// s2.enabledTranList.clear(); +// +// sg.compositeStateMap.remove(s2); +// if(sg.getInitState() == s2){ +// sg.setInitState(s4); +// } +// sg.numTransitions --; +// } +// } +// } +// } +// } +// } +// } +// +//// System.out.println(sg.getLabel() + " case2 transitions: " + trans + " - " + sg.numTransitions); +//// System.out.println(sg.getLabel() + " case2 states: " + states + " - " + sg.numCompositeStates()); +//// long elapsedTimeMillis = System.currentTimeMillis()-start; +//// float elapsedTimeSec = elapsedTimeMillis/1000F; +//// System.out.println(" --> Elapsed time: " + elapsedTimeSec + " sec"); +// } +// +// public void case3(CompositeStateGraph sg){ +// long start = System.currentTimeMillis(); +// int trans = sg.numTransitions; +// int states = sg.numCompositeStates(); +// +// List localTrans = new ArrayList(); +// List localStates = new ArrayList(); +// List nonLocalTrans = new ArrayList(); +// List nonLocalStates = new ArrayList(); +// +// for(Object o : sg.getStateMap().values().toArray()){ +// CompositeState currentState = (CompositeState) o; +// +// List enabledTrans = currentState.enabledTranList; +// List nextStates = currentState.nextStateList; +// +// localTrans.clear(); +// localStates.clear(); +// nonLocalTrans.clear(); +// nonLocalStates.clear(); +// +// for(int i = 0; i < enabledTrans.size(); i++){ +// LPNTran lpnTran = enabledTrans.get(i); +// CompositeState nextState = (nextStates.get(i)); +// if(lpnTran.local()){ +// localTrans.add(lpnTran); +// localStates.add(nextState); +// } +//// else{ +// nonLocalTrans.add(lpnTran); +// nonLocalStates.add(nextState); +//// } +// } +// +// if(nonLocalTrans.isEmpty()){ +// continue; +// } +// +// for(int i = 0; i < localTrans.size(); i++){ +// LPNTran localTran = localTrans.get(i); +// CompositeState s3 = localStates.get(i); +// if(s3.incomingStateList.size() != 1){ +// continue; +// } +//// else if(s3 == sg.getInitState()){ +//// continue; +//// } +// +// List s3Enabled = s3.enabledTranList; +// List s3NextState = s3.nextStateList; +// +// boolean remove = false; +// List removeTran = new ArrayList(); +// +// for(int j = 0; j < s3Enabled.size(); j++){ +// LPNTran nonLocalTran2 = s3Enabled.get(j); +// if(!nonLocalTran2.local()){ +// CompositeState s4 = s3NextState.get(j); +// +// for(int k = 0; k < nonLocalTrans.size(); k++){ +// LPNTran nonLocalTran = nonLocalTrans.get(k); +// if(localTran == nonLocalTran) continue; +// +// CompositeState s2 = nonLocalStates.get(k); +// +// List s2Enabled = s2.enabledTranList; +// List s2NextState = s2.nextStateList; +// for(int n = 0; n < s2Enabled.size(); n++){ +// LPNTran invTran2 = s2Enabled.get(n); +// if(invTran2.local()){ +// CompositeState nextState = s2NextState.get(n); +// +// if(nonLocalTran2 == nonLocalTran && nextState == s4){ +// removeTran.add(nonLocalTran2); +// remove = true; +// } +// } +// } +// } +// } +// } +// +// if(remove){ +// currentState.enabledTranList.remove(localTran); +// currentState.nextStateList.remove(s3); +// sg.numTransitions--; +// +// for(int m = 0; m < s3Enabled.size(); m++){ +// CompositeState currState = s3NextState.get(m); +// LPNTran currTran = s3Enabled.get(m); +// +// if(removeTran.contains(currTran)){ +// removeTran.remove(currTran); +// sg.numTransitions--; +// continue; +// } +// +// currentState.enabledTranList.add(currTran); +// currentState.nextStateList.add(currState); +// +// List currIncomingList = currState.incomingStateList; +// for(int idx = 0; idx < currIncomingList.size(); idx++){ +// if(currIncomingList.get(idx) == s3){ +// currIncomingList.set(idx, currState); +// } +// } +// } +// +// sg.compositeStateMap.remove(s3); +// if(sg.getInitState() == s3){ +// sg.setInitState(currentState); +// } +// +// s3.nextStateList.clear(); +// s3.enabledTranList.clear(); +// s3.incomingStateList.clear(); +// } +// } +// } +// +//// System.out.println(sg.getLabel() + " case3 transitions: " + trans + " - " + sg.numTransitions); +//// System.out.println(sg.getLabel() + " case3 states: " + states + " - " + sg.numCompositeStates()); +//// long elapsedTimeMillis = System.currentTimeMillis()-start; +//// float elapsedTimeSec = elapsedTimeMillis/1000F; +//// System.out.println(" --> Elapsed time: " + elapsedTimeSec + " sec"); +// } + + /** + * Constructs the compositional state graphs. + */ + public static void compositionalFindSG(StateGraph[] sgArray){ +// BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); +// try { +// br.readLine(); +// } catch (IOException e) { +// e.printStackTrace(); +// } + int iter = 0; + int newTransitions = 0; + long start = System.currentTimeMillis(); + HashMap> inputSrcMap = new HashMap>(); + for (StateGraph sg : sgArray) { + LPN lpn = sg.getLpn(); + // Add initial state to state graph + State init = sg.genInitialState(); + sg.setInitialState(init); + sg.addState(init); + sg.addFrontierState(init); + Set inputSet = lpn.getAllInputs().keySet(); + Set outputSet = lpn.getAllOutputs().keySet(); + int numSrc = 0; + // Find lpn interfaces + for(StateGraph sg2 : sgArray){ + if(sg == sg2) + continue; + LPN lpn2 = sg2.getLpn(); + Set outputs = lpn2.getAllOutputs().keySet(); + for(String output : outputs){ + if (inputSet.contains(output)){ + numSrc++; + break; + } + } + for(String output : outputs){ + if (outputSet.contains(output)){ + numSrc++; + break; + } + } + } + List thisInterfaceList = new ArrayList(sgArray.length); + List otherInterfaceList = new ArrayList(sgArray.length); + // TODO: Why designUnitSet.size() + 1 ? +// for(int i = 0; i < designUnitSet.size() + 1; i++){ + for(int i = 0; i < sgArray.length; i++){ + thisInterfaceList.add(null); + otherInterfaceList.add(null); + } + List srcArray = new ArrayList(numSrc); + if(numSrc > 0){ +// int index = 0; + for(StateGraph sg2 : sgArray){ + if(sg == sg2) + continue; + LPN lpn2 = sg2.getLpn(); + int interfaceSize = 0; + Set outputs = lpn2.getAllOutputs().keySet(); + Set inputs = lpn2.getAllInputs().keySet(); + for(String output : outputs){ + if (inputSet.contains(output)){ + interfaceSize++; + } + } + for(String input : inputs){ + if(outputSet.contains(input)){ + interfaceSize++; + } + } + for(String output : outputs){ + if (outputSet.contains(output)){ + interfaceSize++; + } + } + for(String input : inputs){ + if (inputSet.contains(input)){ + interfaceSize++; + } + } + if(interfaceSize > 0){ + int[] thisIndexList = new int[interfaceSize]; + int[] otherIndexList = new int[interfaceSize]; + lpn.genIndexLists(thisIndexList, otherIndexList, lpn2); + thisInterfaceList.set(lpn2.getLpnIndex(), thisIndexList); + otherInterfaceList.set(lpn2.getLpnIndex(), otherIndexList); + // Hao's LPN starting index is 1, whereas ours starts from 0. +// thisInterfaceList.set(lpn2.ID-1, thisIndexList); +// otherInterfaceList.set(lpn2.ID-1, otherIndexList); + srcArray.add(sg2); +// index++; + } + } + } + lpn.setThisIndexList(thisInterfaceList); + lpn.setOtherIndexList(otherInterfaceList); + inputSrcMap.put(sg, srcArray); + } + + // TODO: (temp) designUnitSet has been created already at this point. +// LhpnFile[] lpnList = new LhpnFile[designUnitSet.size()]; +// int idx = 0; +// for (StateGraph sg : designUnitSet) { +// lpnList[idx++] = sg.getLpn(); +// } + constructDstLpnList(sgArray); + // Run initial findSG + for (StateGraph sg : sgArray) { + int result = 0; + if(Options.getStickySemantics()){ +// result = sg.constrStickyFindSG(sg.getInitialState(), emptyTranList); + } + else{ + result = sg.constrFindSG(sg.getInitialState()); + } + newTransitions += result; + } + + long peakUsed = 0; + long peakTotal = 0; + + List newConstraintSet = new ArrayList(); + List oldConstraintSet = new ArrayList(); + while(newTransitions > 0){ + iter++; + newTransitions = 0; + for(StateGraph sg : sgArray){ + sg.genConstraints(); + sg.genFrontier(); + } + // Extract and apply constraints generated from srcSG to sg. + for(StateGraph sg : sgArray){ + for(StateGraph srcSG : inputSrcMap.get(sg)){ + extractConstraints(sg, srcSG, newConstraintSet, oldConstraintSet); + newTransitions += applyConstraintSet(sg, srcSG, newConstraintSet, oldConstraintSet); + } + } + long curTotalMem = Runtime.getRuntime().totalMemory(); + if(curTotalMem > peakTotal) + peakTotal = curTotalMem; + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + if(curUsedMem > peakUsed) + peakUsed = curUsedMem; + } + System.out.println(); + int numStates = 0; +// int numTrans = 0; + int numConstr = 0; + for (StateGraph sg : sgArray) { + sg.genConstraints(); + sg.genFrontier(); + System.out.print(" "); + sg.printStates(); +// sg.clear(); + numStates += sg.reachSize(); +// numTrans += sg.numTransitions(); + numConstr += sg.numConstraints(); + } + + System.out.println("\n --> # states: " + numStates); +// System.out.println(" --> # transitions: " + numTrans); + System.out.println(" --> # constraints: " + numConstr); + System.out.println(" --> # iterations: " + iter); + System.out.println("\n --> Peak used memory: " + peakUsed/1000000F + " MB"); + System.out.println(" --> Peak total memory: " + peakTotal/1000000F + " MB"); + System.out.println(" --> Final used memory: " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1000000F + " MB"); + long elapsedTimeMillis = System.currentTimeMillis()-start; + float elapsedTimeSec = elapsedTimeMillis/1000F; + System.out.println(" --> Elapsed time: " + elapsedTimeSec + " sec"); + if(elapsedTimeSec > 60){ + float elapsedTime = elapsedTimeSec/60; + System.out.println(" --> Elapsed time: " + elapsedTime + " min"); + } + } + + /** + * Constructs the compositional state graphs. + */ + public static void parallelCompositionalFindSG(List designUnitSet){ +// BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); +// try { +// br.readLine(); +// } catch (IOException e) { +// e.printStackTrace(); +// } + + int iter = 0; + int newTransitions = 0; + long start = System.currentTimeMillis(); + HashMap inputSrcMap = new HashMap(); + + for (StateGraph sg : designUnitSet) { + LPN lpn = sg.getLpn(); + + // Add initial state to state graph + State init = sg.genInitialState(); + sg.setInitialState(init); + sg.addState(init); + sg.addFrontierState(init); + + Set inputSet = lpn.getAllInputs().keySet(); + Set outputSet = lpn.getAllOutputs().keySet(); + int size = 0; + + // Find lpn interfaces + for(StateGraph sg2 : designUnitSet){ + if(sg == sg2) continue; + + Set outputs = sg2.getLpn().getAllOutputs().keySet(); + for(String output : outputs){ + if (inputSet.contains(output)){ + size++; + break; + } + } + } + + List thisInterfaceList = new ArrayList(designUnitSet.size() + 1); + List otherInterfaceList = new ArrayList(designUnitSet.size() + 1); + for(int i = 0; i < designUnitSet.size() + 1; i++){ + thisInterfaceList.add(null); + otherInterfaceList.add(null); + } + + StateGraph[] srcArray = new StateGraph[size]; + + if(size > 0){ + int index = 0; + for(StateGraph sg2 : designUnitSet){ + LPN lpn2 = sg2.getLpn(); + if(sg == sg2) continue; + + boolean src = false; + //int interfaceSize = 0; + Set outputs = lpn2.getAllOutputs().keySet(); + for(String output : outputs){ + if (inputSet.contains(output)){ + //interfaceSize++; + src = true; + } + } + + if(src){ + Set inputs = lpn2.getAllInputs().keySet(); + for(String input : inputs){ + if (outputSet.contains(input)){ + //interfaceSize++; + } + } + + for(String input : inputs){ + if (inputSet.contains(input)){ + //interfaceSize++; + } + } + + for(String output : outputs){ + if (outputSet.contains(output)){ + //interfaceSize++; + } + } + + //int[] thisIndexList = new int[interfaceSize]; + //int[] otherIndexList = new int[interfaceSize]; + // TODO: (future) need to add getThisIndexArray in LhpnFile + /* + lpn.genIndexLists(thisIndexList, otherIndexList, lpn2); + + thisInterfaceList.set(lpn2.ID, thisIndexList); + otherInterfaceList.set(lpn2.ID, otherIndexList); + */ + srcArray[index] = sg2; + index++; + } + } + } + lpn.setThisIndexList(thisInterfaceList); + lpn.setOtherIndexList(otherInterfaceList); + inputSrcMap.put(sg, srcArray); + } + + LPN[] lpnList = new LPN[designUnitSet.size()]; + + int idx = 0; + for (StateGraph sg : designUnitSet) { + lpnList[idx] = sg.getLpn(); + idx++; + } + + // Run initial findSG + for (StateGraph sg : designUnitSet) { + int result = sg.constrFindSG(sg.getInitialState()); + newTransitions += result; + } + + long peakUsed = 0; + long peakTotal = 0; + + CompositionalThread[] threadArray = new CompositionalThread[designUnitSet.size()]; + while(newTransitions > 0){ + iter++; + newTransitions = 0; + + for(StateGraph sg : designUnitSet){ + sg.genConstraints(); + sg.genFrontier(); + } + + int t = 0; + for(StateGraph sg : designUnitSet){ + CompositionalThread newThread = new CompositionalThread(sg, inputSrcMap.get(sg), iter); + newThread.start(); + threadArray[t++] = newThread; + } + + for(CompositionalThread p : threadArray){ + try { + p.join(); + newTransitions += p.getNewTransitions(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + long curTotalMem = Runtime.getRuntime().totalMemory(); + if(curTotalMem > peakTotal) + peakTotal = curTotalMem; + + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + if(curUsedMem > peakUsed) + peakUsed = curUsedMem; + } + + System.out.println(); + + int numStates = 0; + int numTrans = 0; + int numConstr = 0; + for (StateGraph sg : designUnitSet) { + System.out.print(" "); + sg.printStates(); + + numStates += sg.reachSize(); + //numTrans += sg.numTransitions(); + numConstr += sg.numConstraints(); + } + + System.out.println("\n --> # states: " + numStates); + System.out.println(" --> # transitions: " + numTrans); + System.out.println(" --> # constraints: " + numConstr); + System.out.println(" --> # iterations: " + iter); + + System.out.println("\n --> Peak used memory: " + peakUsed/1000000F + " MB"); + System.out.println(" --> Peak total memory: " + peakTotal/1000000F + " MB"); + System.out.println(" --> Final used memory: " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1000000F + " MB"); + + long elapsedTimeMillis = System.currentTimeMillis()-start; + float elapsedTimeSec = elapsedTimeMillis/1000F; + System.out.println(" --> Elapsed time: " + elapsedTimeSec + " sec"); + + if(elapsedTimeSec > 60){ + float elapsedTime = elapsedTimeSec/60; + System.out.println(" --> Elapsed time: " + elapsedTime + " min"); + } + } + + /** + * Applies new constraints to the entire state set, and applies old constraints to the frontier state set. + * @return Number of new transitions. + */ + private static int applyConstraintSet(StateGraph sg, StateGraph srcSG, List newConstraintSet, List oldConstraintSet){ + int newTransitions = 0; + LPN srcLpn = srcSG.getLpn(); + LPN lpn = sg.getLpn(); + int[] thisIndexList = lpn.getThisIndexArray(srcLpn.getLpnIndex()); + int[] otherIndexList = lpn.getOtherIndexArray(srcLpn.getLpnIndex()); +// int[] thisIndexList = lpn.getThisIndexArray(srcLpn.ID - 1); +// int[] otherIndexList = lpn.getOtherIndexArray(srcLpn.ID - 1); + if(newConstraintSet.size() > 0){ + for(State currentState : sg.getStateSet()){ + for(Constraint c : newConstraintSet){ + if(compatible(currentState, c, thisIndexList, otherIndexList)){ + newTransitions += createNewState(sg, currentState, c); + } + } + } + for(State currentState : sg.getFrontierStateSet()){ + for(Constraint c : newConstraintSet){ + if(compatible(currentState, c, thisIndexList, otherIndexList)){ + newTransitions += createNewState(sg, currentState, c); + } + } + } + } + if(oldConstraintSet.size() > 0){ + for(State currentState : sg.getFrontierStateSet()){ + for(Constraint c : oldConstraintSet){ + if(compatible(currentState, c, thisIndexList, otherIndexList)){ + newTransitions += createNewState(sg, currentState, c); + } + } + } + } + return newTransitions; + } + + /** + * Extracts applicable constraints from a StateGraph. + * @param sg - The state graph the constraints are to be applied. + * @param srcSG - The state graph the constraint are extracted from. + */ + private static void extractConstraints(StateGraph sg, StateGraph srcSG, List newConstraintSet, List oldConstraintSet){ + newConstraintSet.clear(); + oldConstraintSet.clear(); + LPN srcLpn = srcSG.getLpn(); + for(Constraint newConstraint : sg.getNewConstraintSet()){ + if(newConstraint.getLpn() != srcLpn) + continue; + newConstraintSet.add(newConstraint); + } + for(Constraint oldConstraint : sg.getOldConstraintSet()){ + if(oldConstraint.getLpn() != srcLpn) + continue; + oldConstraintSet.add(oldConstraint); + } + } + + /** + * Determines whether a constraint is compatible with a state. + * @return True if compatible, otherwise False. + */ + private static boolean compatible(State currentState, Constraint constr, int[] thisIndexList, int[] otherIndexList){ + int[] constraintVector = constr.getVector(); + int[] currentVector = currentState.getVariableVector(); + for(int i = 0; i < thisIndexList.length; i++){ + int thisIndex = thisIndexList[i]; + int otherIndex = otherIndexList[i]; + if(currentVector[thisIndex] != constraintVector[otherIndex]){ + return false; + } + } + return true; + } + + /** + * Creates a state from a given constraint and compatible state and insert into state graph. If the state is new, then findSG is called. + * @return Number of new transitions. + */ + private static int createNewState(StateGraph sg, State compatibleState, Constraint c){ + int newTransitions = 0; + State newState = new State(compatibleState); + int[] newVector = newState.getVariableVector(); + //List variableList = c.getVariableList(); + List variableList = c.getVariableList(); + List valueList = c.getValueList(); + + //int[] compatibleVector = compatibleState.getVector(); + // TODO: Need to update tranVector here? + for(int i = 0; i < variableList.size(); i++){ + //int index = variableList.get(i).getIndex(compatibleVector); + int index = variableList.get(i); + newVector[index] = valueList.get(i); + } + updateTranVectorByConstraint(newState.getLpn(), newState.getTranVector(), newState.getMarking(), newVector); + State nextState = sg.addState(newState); + if(nextState == newState){ + int result = 0; + sg.addFrontierState(nextState); + // TODO: Need to consider the "Sticky sematics" +// if(Options.getStickySemantics()){ +// result = sg.constrStickyFindSG(nextState, sg.getEnabled(compatibleState)); +// } +// else{ + result = sg.constrFindSG(nextState); +// } + if(result < 0) + return newTransitions; + newTransitions += result; + } + Transition constraintTran = c.getLpnTransition(); + sg.addStateTran(compatibleState, constraintTran, nextState); + newTransitions++; + return newTransitions; + } + + @SuppressWarnings("unused") + private static String printTranVecotr(boolean[] tranVector) { + String tranVecStr = "["; + for (boolean i : tranVector) { + tranVecStr = tranVecStr + "," + i; + } + tranVecStr = tranVecStr + "]"; + return tranVecStr; + } + + /** + * Update tranVector due to application of a constraint. Only vector of a state can change due to a constraint, and + * therefore the tranVector can potentially change. + * @param lpn + * @param enabledTranBeforeConstr + * @param marking + * @param newVector + * @return + */ + public static void updateTranVectorByConstraint(LPN lpn, boolean[] enabledTran, + int[] marking, int[] newVector) { + // find newly enabled transition(s) based on the updated variables vector. + for (Transition tran : lpn.getAllTransitions()) { + boolean needToUpdate = true; + String tranName = tran.getLabel(); + int tranIndex = tran.getIndex(); + if (Options.getDebugMode()) { +// System.out.println("Checking " + tranName); + } + if (lpn.getEnablingTree(tranName) != null + && lpn.getEnablingTree(tranName).evaluateExpr(lpn.getAllVarsWithValuesAsString(newVector)) == 0.0) { + if (Options.getDebugMode()) { + System.out.println(tran.getLabel() + " " + "Enabling condition is false"); + } + if (enabledTran[tranIndex] && !tran.isPersistent()) + enabledTran[tranIndex] = false; + continue; + } + if (lpn.getTransitionRateTree(tranName) != null + && lpn.getTransitionRateTree(tranName).evaluateExpr(lpn.getAllVarsWithValuesAsString(newVector)) == 0.0) { + if (Options.getDebugMode()) { + System.out.println("Rate is zero"); + } + continue; + } + if (lpn.getPreset(tranName) != null && lpn.getPreset(tranName).length != 0) { + for (int place : lpn.getPresetIndex(tranName)) { + if (marking[place]==0) { + if (Options.getDebugMode()) { + System.out.println(tran.getLabel() + " " + "Missing a preset token"); + } + needToUpdate = false; + break; + } + } + } + if (needToUpdate) { + enabledTran[tranIndex] = true; + if (Options.getDebugMode()) { + System.out.println(tran.getLabel() + " is Enabled."); + } + } + } + } + + private static void constructDstLpnList(StateGraph[] sgArray) { + for (int i=0; i + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.logicAnalysis; + +import java.util.ArrayList; +import java.util.List; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class CompositionalThread extends Thread{ + + private StateGraph[] srcArray = null; + private StateGraph sg = null; + private int iter = 0; + private int newTransitions = 0; + + public CompositionalThread(StateGraph sg, StateGraph[] srcArray, int iter){ + this.srcArray = srcArray; + this.sg = sg; + this.iter = iter; + } + + public int getNewTransitions(){ + return this.newTransitions; + } + + public StateGraph getStateGraph(){ + return this.sg; + } + + @Override + public void run(){ + List newConstraintSet = new ArrayList(); + List oldConstraintSet = new ArrayList(); + + for(StateGraph srcSG : this.srcArray){ + extractConstraints(sg, srcSG, newConstraintSet, oldConstraintSet); + newTransitions += applyConstraintSet(sg, srcSG, iter, newConstraintSet, oldConstraintSet); + } + } + + /** + * Applies new constraints to the entire state set, and applies old constraints to the frontier state set. + * @return Number of new transitions. + */ + private static int applyConstraintSet(StateGraph sg, StateGraph srcSG, int iter, List newConstraintSet, List oldConstraintSet){ + int newTransitions = 0; +// int[] thisIndexList = null; +// int[] otherIndexList = null; +// +// String label = srcSG.getLabel(); +// String[] indexArray = sg.getKeyArray(); +// +// for(int i = 0; i < indexArray.length; i++){ +// if(label == indexArray[i]){ +// thisIndexList = sg.getThisIndexArray(i); +// otherIndexList = sg.getOtherIndexArray(i); +// break; +// } +// } + +// int index = sg.getInterfaceIndex(srcSG.getLabel()); +// int[] thisIndexList = sg.getThisIndexArray(index); +// int[] otherIndexList = sg.getOtherIndexArray(index); + //LhpnFile srcLpn = srcSG.getLpn(); + //LhpnFile lpn = sg.getLpn(); + + // TODO: (future)need to add getThisIndexArray in LhpnFile. + /* + int[] thisIndexList = lpn.getThisIndexArray(srcLpn.ID); + int[] otherIndexList = lpn.getOtherIndexArray(srcLpn.ID); + + if(newConstraintSet.size() > 0){ + for(Object obj : sg.getStateSet().toArray()){ + platu.stategraph.State currentState = (platu.stategraph.State) obj; + + for(Constraint c : newConstraintSet){ + if(compatible(currentState, c, thisIndexList, otherIndexList)){ + newTransitions += createNewState(sg, currentState, c); + } + } + } + + for(platu.stategraph.State currentState : sg.getFrontierStateSet()){ + for(Constraint c : newConstraintSet){ + if(compatible(currentState, c, thisIndexList, otherIndexList)){ + newTransitions += createNewState(sg, currentState, c); + } + } + } + } + + if(oldConstraintSet.size() > 0){ + for(platu.stategraph.State currentState : sg.getFrontierStateSet()){ + for(Constraint c : oldConstraintSet){ + if(compatible(currentState, c, thisIndexList, otherIndexList)){ + newTransitions += createNewState(sg, currentState, c); + } + } + } + } + */ + return newTransitions; + } + + /** + * Extracts applicable constraints from a StateGraph. + * @param sg The state graph the constraints are to be applied. + * @param srcSG The state graph the constraint are extracted from. + */ + private static void extractConstraints(StateGraph sg, StateGraph srcSG, List newConstraintSet, List oldConstraintSet){ + newConstraintSet.clear(); + oldConstraintSet.clear(); + LPN srcLpn = srcSG.getLpn(); + for(Constraint newConstraint : sg.getNewConstraintSet()){ + if(newConstraint.getLpn() != srcLpn) continue; + newConstraintSet.add(newConstraint); + } + for(Constraint oldConstraint : sg.getOldConstraintSet()){ + if(oldConstraint.getLpn() != srcLpn) continue; + oldConstraintSet.add(oldConstraint); + } + } + + /** + * Determines whether a constraint is compatible with a state. + * @return True if compatible, otherwise False. + */ + @SuppressWarnings("unused") + private static boolean compatible(edu.utah.ece.async.lema.verification.platu.stategraph.State currentState, Constraint constr, int[] thisIndexList, int[] otherIndexList){ + int[] constraintVector = constr.getVector(); + int[] currentVector = currentState.getVariableVector(); + + for(int i = 0; i < thisIndexList.length; i++){ + int thisIndex = thisIndexList[i]; + int otherIndex = otherIndexList[i]; + + if(currentVector[thisIndex] != constraintVector[otherIndex]){ + return false; + } + } + + return true; + } + + /** + * Creates a state from a given constraint and compatible state. If the state is new, then findSG is called. + * @return Number of new transitions. + */ + @SuppressWarnings("unused") + private static int createNewState(StateGraph sg, edu.utah.ece.async.lema.verification.platu.stategraph.State compatibleState, Constraint c){ + int newTransitions = 0; + + // Create new state and insert into state graph + edu.utah.ece.async.lema.verification.platu.stategraph.State newState = new edu.utah.ece.async.lema.verification.platu.stategraph.State(compatibleState); + int[] newVector = newState.getVariableVector(); + + //List variableList = c.getVariableList(); + List variableList = c.getVariableList(); + List valueList = c.getValueList(); + + //int[] compatibleVector = compatibleState.getVector(); + for(int i = 0; i < variableList.size(); i++){ + //int index = variableList.get(i).getIndex(compatibleVector); + int index = variableList.get(i); + newVector[index] = valueList.get(i); + } + + edu.utah.ece.async.lema.verification.platu.stategraph.State nextState = sg.addState(newState); + if(nextState == newState){ + int result = sg.synchronizedConstrFindSG(nextState); + if(result < 0) return newTransitions; + +// sg.initializeTranList(nextState); + newTransitions += result; + } + +// StateTran stTran = new StateTran(compatibleState, constraintTran, state); + + Transition constraintTran = c.getLpnTransition(); +// constraintTran.synchronizedAddStateTran(compatibleState, nextState); +// sg.addEnabledTran(compatibleState, constraintTran); + newTransitions++; + + return newTransitions; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/Constraint.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/Constraint.java new file mode 100644 index 000000000..86c88699a --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/Constraint.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.logicAnalysis; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.platuLpn.DualHashMap; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Constraint{ + private LPN lpn; // lpn that generates the constraint + final private int[] interfaceValues; + final private Transition lpnTransition; + final private int[] vector; + //List variableList = new ArrayList(1); + List variableList = new ArrayList(1); // variableList stores the index of interface variables in the other lpn. + List valueList = new ArrayList(1); + private int hashVal = -1; + + public Constraint(State start, State end, Transition firedTran, LPN lpn2) { + this.lpnTransition = firedTran; + this.lpn = firedTran.getLpn(); + this.vector = start.getVariableVector(); + + int[] endVector = end.getVariableVector(); +// int index = dstLpn.getInterfaceIndex(this.lpn.getLabel()); + //int[] thisIndex = lpn2.getOtherIndexArray(this.lpn.ID-1); + int[] thisIndex = lpn2.getOtherIndexArray(this.lpn.getLpnIndex()); + DualHashMap varIndexMap = this.lpn.getVarIndexMap(); + + this.interfaceValues = new int[thisIndex.length]; + for(int i = 0; i < thisIndex.length; i++){ + int varIndex = thisIndex[i]; + this.interfaceValues[i] = this.vector[varIndex]; + if(this.vector[varIndex] != endVector[varIndex]){ + String variable = varIndexMap.getKey(varIndex); + this.valueList.add(endVector[varIndex]); + this.variableList.add(lpn2.getVarIndexMap().get(variable)); + //this.variableList.add(lpn2.getVarNodeMap().get(variable)); + } + } + if(this.variableList.size() == 0){ + System.out.println(this.lpnTransition.getFullLabel()); + System.err.println("error: invalid constraint"); + System.exit(1); + } + } + + /** + * @return List of modified variables. + */ + public List getVariableList(){ + return this.variableList; + } + + /** + * @return List of new variable values. + */ + public List getValueList(){ + return this.valueList; + } + + /** + * @return State vector. + */ + public int[] getVector(){ + return this.vector; + } + + /** + * @return LPN where the constraint was generated. + */ + public LPN getLpn(){ + return this.lpn; + } + + /** + * @return Values of the interface variables. + */ + public int[] getInterfaceValue(){ + return this.interfaceValues; + } + + /** + * @return LPNTran applied. + */ + public Transition getLpnTransition(){ + return this.lpnTransition; + } + + @Override + public int hashCode() { + if(this.hashVal == -1){ + final int prime = 31; + this.hashVal = 1; + this.hashVal = prime * this.hashVal + Arrays.hashCode(interfaceValues); + this.hashVal = prime * this.hashVal + ((this.lpn == null) ? 0 : this.lpn.getLabel().hashCode()); + this.hashVal = prime * this.hashVal + ((this.lpnTransition == null) ? 0 : this.lpnTransition.hashCode()); + } + + return this.hashVal; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + + if (obj == null) + return false; + + if (getClass() != obj.getClass()) + return false; + + Constraint other = (Constraint) obj; + if (!Arrays.equals(this.interfaceValues, other.interfaceValues)) + return false; + + if (this.lpn == null) { + if (other.lpn != null) + return false; + } + else if (!this.lpn.equals(other.lpn)) + return false; + + if (this.lpnTransition == null) { + if (other.lpnTransition != null) + return false; + } + else if (!this.lpnTransition.equals(other.lpnTransition)) + return false; + + return true; + } + + @Override + public String toString() { + return "Constraint [lpn=" + lpn.getLabel() + ",\n interfaceValues=" + + Arrays.toString(interfaceValues) + ",\n lpnTransition=" + + lpnTransition + ",\n vector=" + Arrays.toString(vector) + + ",\n variableList=" + variableList + ",\n valueList=" + valueList + + "]"; + } + + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/HashSetWrapper.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/HashSetWrapper.java new file mode 100644 index 000000000..0f01f202e --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/HashSetWrapper.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.logicAnalysis; + +import java.util.HashSet; + +import edu.utah.ece.async.lema.verification.platu.project.PrjState; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class HashSetWrapper extends HashSet implements StateSetInterface { + + private static final long serialVersionUID = 1L; + + @Override + public boolean contains(PrjState state) { + return super.contains(state); + } + + @Override + public boolean add(PrjState state) { + return super.add(state); + } + + /** + * This method takes a PrjState instance otherPrjState, iterates through this hash set of PrjState instances, + * and grabs the one from this set that "equals" to otherPrjState. If no match is found, this method returns null. + * @param otherPrjState + * @return + */ + public PrjState get(PrjState otherPrjState) { + for (PrjState prjSt : this) { + if (this.contains(otherPrjState)) + return prjSt; + } + return null; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/LpnState.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/LpnState.java new file mode 100644 index 000000000..810c83839 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/LpnState.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.logicAnalysis; + + +import java.util.*; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.common.PlatuObj; +import edu.utah.ece.async.lema.verification.platu.stategraph.*; + +/** + * State + * @author Administrator + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class LpnState extends PlatuObj { + + private LPN lpn; + private State state; + private HashSet enabledSet; + int index; + + + + public LpnState() { + this.lpn = null; + this.state = null; + this.enabledSet = null; + this.index = -1; + } + + public LpnState(final LPN lhpnFile, final State newState, final HashSet lpnEnabledSet) { + this.lpn = lhpnFile; + this.state = newState; + this.enabledSet = lpnEnabledSet; + } + + public void setLpn(final LPN thisLpn) { + this.lpn = thisLpn; + } + + public LPN getLpn() { + return this.lpn; + } + + public void setState(State newState) { + this.state = newState; + } + + @Override + public void setLabel(String lbl) { + + } + + @Override + public String getLabel() { + return null; + } + + @Override + public void setIndex(int i) { + this.index = i; + } + + @Override + public int getIndex() { + return this.index; + } + + @Override + public LpnState clone() { + LpnState copy = new LpnState(); + copy.lpn = this.lpn; + copy.state = this.state; + copy.enabledSet = this.enabledSet; + return copy; + } + + @Override + public int hashCode() { + final int prime = 13; + int result = Integer.rotateLeft(this.state.hashCode(), prime) ^ Integer.rotateLeft(this.enabledSet.hashCode(), prime); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + + if (obj == null) + return false; + + + LpnState other = (LpnState) obj; + if(this.lpn != other.lpn) + return false; + + if(this.state != other.state) + return false; + + if(this.enabledSet.equals(other.enabledSet)==false) + return false; + + return true; + } + + + public State getState() { + return this.state; + } + + public HashSet getEnabled() { + return this.enabledSet; + } +} + diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/PrjLpnState.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/PrjLpnState.java new file mode 100644 index 000000000..4977790a7 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/PrjLpnState.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.logicAnalysis; + +import java.util.*; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class PrjLpnState { + + protected LpnState[] stateArray; + + + public PrjLpnState() { + stateArray = null; + } + + public PrjLpnState(final LpnState[] other) { + stateArray = other; + } + + @Override + public boolean equals(final Object other) { + PrjLpnState otherState = (PrjLpnState)other; + + if(this.stateArray == otherState.stateArray) + return true; + + if(this.stateArray.length != otherState.stateArray.length) + return false; + + for(int i = 0; i < this.stateArray.length; i++) + if(this.stateArray[i] != otherState.stateArray[i]) + return false; + + return true; + } + + @Override + public int hashCode() { + // This hash funciton is much faster, but uses a lot more memory + return Arrays.hashCode(stateArray); + + // THe following hashing approach uses less memory, but becomes slower + // as it causes a lot of hash collisions when the number of states grows. +// int hashVal = 0; +// for(int i = 0; i < stateArray.length; i++) { +// if(i == 0) +// hashVal = Integer.rotateLeft(stateArray[i].hashCode(), stateArray.length - i); +// else +// hashVal = hashVal ^ Integer.rotateLeft(stateArray[i].hashCode(), stateArray.length - i); +// } +// return hashVal; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/StateSetInterface.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/StateSetInterface.java new file mode 100644 index 000000000..1328bc37c --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/logicAnalysis/StateSetInterface.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.logicAnalysis; + +import edu.utah.ece.async.lema.verification.platu.project.PrjState; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public interface StateSetInterface extends Iterable { + + public boolean contains(PrjState state); + + public boolean add(PrjState state); + + public int size(); + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/main/Interpretor.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/main/Interpretor.java new file mode 100644 index 000000000..8d7d57639 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/main/Interpretor.java @@ -0,0 +1,233 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package edu.utah.ece.async.lema.verification.platu.main; + +import java.io.File; +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.StringTokenizer; +import java.util.logging.Level; +import java.util.logging.Logger; + +import edu.utah.ece.async.ibiosim.dataModels.util.exceptions.BioSimException; +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.platu.project.Project; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Interpretor { + + public static boolean OLD_LPN = false; + private boolean readFlag = false; + final int MAXHISTORY = 10; + boolean FLATMODEL = false; + String[] commandHistory = new String[MAXHISTORY]; + static final LinkedHashMap mapCMD = (new LinkedHashMap(20)); + static final LinkedHashMap mapDesc = (new LinkedHashMap(20)); + + enum enCMD { + compAnalysis, findallsg, skip, set, last, liststg, sglist, readcsp, + setinterface, savesg, savelpn, join, compose, removedummypn, + rdpn, findsg, findrsg, simulate, sim, getsg, addenv, + flattenpns, mergebgpnall, getsgmaximal, getsgmaxenv, getsgflat, + mergesg, sgabst, abstractsg, sgaf, autofailure, + sgreduce, reduce, deletesg, help, quit, q, interactive, + print, chkpie, sghide, abstStateTran, hidevar, readrsg, + readlpn, chkpi, del, draw + } + + static final String[] CMD = {"compAnalysis", "findallsg", "skip", "set", "last", "liststg", "sglist", "readcsp", + "setinterface", "savesg", "savelpn", "join", "compose", "removedummypn", + "rdpn", "findsg", "findrsg", "simulate", "sim", "getsg", "addenv", + "flattenpns", "mergebgpnall", "getsgmaximal", "getsgmaxenv", "getsgflat", + "mergesg", "sgabst", "abstractsg", "sgaf", "autofailure", + "sgreduce", "reduce", "deletesg", "help", "quit", "q", "interactive", + "print", "chkpie", "sghide", "abstStateTran", "hidevar", "readrsg", + "readlpn", "chkpi", "del", "draw" + }; + static final String[] CMDDesc = { + "[compAnalysis]", "[findallsg]", " [skip]", " [set]", "re-enter last command", " [liststg]", " [sglist]", " [readcsp]", + " [setinterface]", "+ [savesg]", "+ [savelpn]", "+ [join]", "+ [compose]", " [removedummypn]", + " [rdpn]", "+ [findsg]", "+ [findrsg]", "+ [simulate]", "+ [sim]", "+ [getsg]", " [addenv]", + " [flattenpns]", "+ [mergebgpnall]", " [getsgmaximal]", " [getsgmaxenv]", " [getsgflat]", + " [mergesg]", " [sgabst]", " [abstractsg]", " [sgaf]", " [autofailure]", + " [sgreduce]", " [reduce]", " [deletesg]", "+ [help]", "+ [quit]", "+ [q]", "+ [interactive]", + "+ [print]", " [chkpie]", " [sghide]", " [abstStateTran]", " [hidevar]", " [readrsg]", + "+ [readlpn]", " [chkpi]", " [del]", " [draw]" + }; + + static { + int x = 0; + for (enCMD en : enCMD.values()) { + mapCMD.put(en, CMD[x]); + mapDesc.put(en, CMDDesc[x]); + x++; + } + } + + public int interpretcommand(Project prj, final String commandline) throws BioSimException { + if (prj == null) { + new Exception("Main: interpretcommand: prj is NULL").printStackTrace(); + return 0; + } + + //String systemcommand = commandline; + //systemcommand += " "; + LinkedList arguments = new LinkedList(); + String command; + String argument1 = ""; + + // parse commandline and place command and arguements into list + String buffer = commandline; + StringTokenizer tk = new StringTokenizer(buffer, " "); + while (tk.hasMoreTokens()) { + arguments.add(tk.nextToken()); + } + + // make sure there is a command to execute + if (arguments.size() == 0) { + return 0; + } + + // remove command from argument list + command = arguments.removeFirst(); + + int argumentcount = arguments.size(); + if (arguments.size() > 0) { + argument1 = arguments.peekFirst(); + } + + // mode changes + if (command.charAt(0) == '/' && command.charAt(1) == '/') { + return 0; + } else if (command.compareToIgnoreCase(mapCMD.get(enCMD.skip)) == 0) { + return 0; + } else if (command.compareToIgnoreCase(mapCMD.get(enCMD.del)) == 0) { + for (StateGraph sg : prj.getDesignUnitSet()) { + LPN lpn = sg.getLpn(); + + if (lpn.getLabel().compareTo(argument1) == 0) { + prj.getDesignUnitSet().remove(lpn); + } + } + } else if (command.compareToIgnoreCase(mapCMD.get(enCMD.last)) == 0) { + int x = 1; + for (; x < MAXHISTORY; x++) { + System.out.printf("\t%d\t%s\n", x, commandHistory[x]); + } + + System.out.printf("enter choice: "); + try { + x = System.in.read() - '0'; + } catch (IOException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + } + + int ret = interpretcommand(prj, commandHistory[x]);//!! + return (ret); + } else if (command.compareToIgnoreCase(mapCMD.get(enCMD.rdpn)) == 0 + || command.compareToIgnoreCase(mapCMD.get(enCMD.removedummypn)) == 0) { + //if( argument1 != "" ) + //prj.removeDummyPN( argument1 ); + } else if (command.compareToIgnoreCase(mapCMD.get(enCMD.findsg)) == 0) { + if (argumentcount > 0) { + prj.search(); + } else { + prj.search(); + } + } else if (command.compareToIgnoreCase(mapCMD.get(enCMD.findallsg)) == 0) { + prj.search(); + } else if (command.compareToIgnoreCase(mapCMD.get(enCMD.findrsg)) == 0) { + prj.search(); + }else if (command.compareToIgnoreCase(mapCMD.get(enCMD.compAnalysis)) == 0) { + prj.search(); + }else if (command.compareToIgnoreCase(mapCMD.get(enCMD.draw)) == 0){ + if(argumentcount > 0){ + for(StateGraph sg : prj.getDesignUnitSet()){ + LPN lpn = sg.getLpn(); + + if(argument1.equals(lpn.getLabel())){ + System.out.print("drawing " + lpn.getLabel() + "..."); + sg.draw(); + System.out.println("Done"); + } + } + } + else{ + for(StateGraph sg : prj.getDesignUnitSet()){ + LPN lpn = sg.getLpn(); + System.out.print("drawing " + lpn.getLabel() + "..."); + sg.draw(); + System.out.println("Done"); + } + } + } else if (command.compareToIgnoreCase(mapCMD.get(enCMD.help)) == 0) { + System.out.printf("%15s | %s\n" + + "----------------------------------------------------\n", "Command", "Description"); + for (enCMD cmd : enCMD.values()) {//!! + System.out.printf("%15s | %s\n", mapCMD.get(cmd), mapDesc.get(cmd)); + //prln( CMD[cmd] + " | " + CMDDESC[cmd] ); + } + } else if (command.compareToIgnoreCase(mapCMD.get(enCMD.q)) == 0 + || command.compareToIgnoreCase(mapCMD.get(enCMD.quit)) == 0) { + return 1; + } else if (command.compareToIgnoreCase(mapCMD.get(enCMD.readlpn)) == 0) { + if(!readFlag){ + readFlag = true; + + LinkedList fileList = new LinkedList(); + for(String arg : arguments){ + File f = new File(arg); + fileList.add(f.getAbsolutePath()); + } + + prj.readLpn(fileList); + } + else{ + File f = new File(argument1); + Project.readLpn(f.getAbsolutePath()); + } + } + + return 0; + } + + static String mergeColumns(String a, String b) { + String ret = ""; + StringTokenizer tk1 = new StringTokenizer(a, "\n"); + StringTokenizer tk2 = new StringTokenizer(b, "\n"); + while (tk1.hasMoreTokens() && tk2.hasMoreTokens()) { + ret += tk1.nextToken() + "\t" + tk2.hasMoreTokens() + "\n"; + } + while (tk1.hasMoreTokens()) { + ret += tk1.nextToken() + "\n"; + } + while (tk2.hasMoreTokens()) { + ret += tk2.hasMoreTokens() + "\n"; + } + return ret; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/main/Main.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/main/Main.java new file mode 100644 index 000000000..133526eba --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/main/Main.java @@ -0,0 +1,377 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.main; + +import java.util.concurrent.Executors; + +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.project.Project; + +import java.util.concurrent.ExecutorService; +import java.io.FileReader; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.text.SimpleDateFormat; +import java.util.Properties; +import java.util.StringTokenizer; +import static java.lang.Runtime.*; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Main { + + // static variables + public final static int PROCESSORS = Runtime.getRuntime().availableProcessors(); + public final static int THREADS = PROCESSORS; + public final static boolean isWindows = System.getProperty("os.name").toLowerCase().contains("windows"); + public static final SimpleDateFormat dateAndTime = new SimpleDateFormat("yyyy-MMM-dd hh.mm.ss a"); + public static String workingDirectory = System.getProperty("user.dir"); + +// static{ +// System.out.println(System.getProperty("user.dir")); +// System.out.println("CORES: " + PROCESSORS); +// System.out.println("isWindows: " + isWindows); +// } + + public static ExecutorService exec = Executors.newFixedThreadPool(PROCESSORS); + + // options + public static boolean ZONE_OPTIMIZE_INF = false; + public static int ZONE_VERSION = 3; + public static long GRAPH_KEEP_ALIVE_TIME = 3000;//millisec + public static boolean ZONE_ENABLE_PRINT = false; + public static boolean PRINT_USAGE_STATS = false; + public static boolean REMOVE_DUMMY = false; + public static boolean FIND_FAILURE = true; + public static boolean SHOW_SIGNALS = false; + public static boolean SHOW_FAILURES = true; + public static boolean NO_DATE = true; + public static boolean PRINT_FINAL_SUMMARY = false; + public static long MAX_MEM = 0; + public static long MAX_STACK_HEIGHT = Long.MAX_VALUE; + public static boolean PRINT_MAIN = false; + public static boolean ENABLE_LOGGING = false; + + private static void start(String cmdFile) { + try { + BufferedReader br = null; + + if (cmdFile != null) { + br = new BufferedReader(new FileReader(cmdFile)); + } else { + br = new BufferedReader(new InputStreamReader(System.in)); + } + + long memUse; + Interpretor in = new Interpretor(); + Project prj = new Project(); + + while (true) { + String commandline = null; + commandline = br.readLine(); + + if (commandline == null) break; + + if(commandline.equalsIgnoreCase("reset")){ + prj = new Project(); + } + + if (in.interpretcommand(prj, commandline) == 1) { + memUse = getRuntime().totalMemory() - getRuntime().freeMemory(); + MAX_MEM = MAX_MEM > memUse ? MAX_MEM : memUse; + break; + } + } + + br.close(); + + } catch (java.io.FileNotFoundException ex) { + System.err.println("file not found: " + new File(cmdFile).getAbsoluteFile()); + ex.printStackTrace(); + System.exit(1); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + /** + * + * @param args + */ + public static void main(String[] args) { + try { + String optFileString = null, cmdFileString = null; +// String switches = ""; + for (String arg : args) { + if (arg.startsWith("/")) { + // switches += arg + "\n"; + } + else if (arg.endsWith(".cmd") || arg.endsWith(".cmnd")) { + cmdFileString = arg; + } + else if (arg.endsWith(".opt") || arg.endsWith(".cfg") || arg.endsWith(".conf")) { + optFileString = arg; + } + } + + String path = optFileString != null ? optFileString : cmdFileString; + if (path != null) { + File f = new File(path); + path = f.getAbsoluteFile().getParentFile().getAbsolutePath(); + } + else { + path = System.getProperty("user.dir"); + } + + File optFile = null; + if (optFileString != null) { + optFile = new File(optFileString); + if (!optFile.exists()) { + System.err.println("file not found: " + optFile.getAbsolutePath()); + } + + // load options + Properties prop = new Properties(); + prop.load(new FileInputStream(optFile)); + setOptions(prop); + } + + Main.start(cmdFileString); + +// if (PRINT_USAGE_STATS) { +// VarVal.printUsageStats(); +// LPNTran.printUsageStats(); +//// TimedStateGraph.printUsageStats(); +//// if (AbstractStateGraph.TIMED_ANALYSIS) { +//// TimedState.printUsageStats(); +//// } else { +//// State.printUsageStats(); +//// +//// } +// } + } + catch (Throwable e) { + e.printStackTrace(); + System.exit(1); + } + } + + static void setOptions(Properties prop) throws Exception { + String value = prop.getProperty("DOT_PATH"); + if(value != null) Options.setDotPath(value); + + value = prop.getProperty("VERBOSITY"); + if(value != null){ + int verbosity = 0; + + try{ + verbosity = Integer.parseInt(value); + Options.setVerbosity(verbosity); + } + catch(Exception e){ + System.out.println("warning: verbosity option is not valid - default is 0"); + } + } + + value = prop.getProperty("TIMING_ANALYSIS"); + if(value != null){ + Options.setTimingAnalsysisType(value); + } + + value = prop.getProperty("COMPOSITIONAL_MINIMIZATION"); + if(value != null){ + Options.setCompositionalMinimization(value); + } + + value = prop.getProperty("POR"); + if(value != null) Options.setPOR(value); + + value = prop.getProperty("SEARCH"); + if(value != null) Options.setSearchType(value); + + value = prop.getProperty("STATE_FORMAT"); + if(value != null) Options.setStateFormat(value); + + value = prop.getProperty("NEW_PARSER_FLAG"); + if(value != null) if(value.equals("true") || value.equals("TRUE")) Options.setNewParser(); + + value = prop.getProperty("STICKY_SEMANTICS"); + if(value != null) if(value.equals("true") || value.equals("TRUE")) Options.setStickySemantics(); + + value = prop.getProperty("PARALLEL"); + if(value != null) if(value.equals("true") || value.equals("TRUE")) Options.setParallelFlag(); + } + +// static Properties storeOptions(File propFile) throws Exception { +// Properties prop = new Properties(); +//// prop.put("StateGraph.MAINTAIN_STATE_TRAN_LIST", "" + TimedStateGraph.MAINTAIN_STATE_TRAN_LIST); +//// prop.put("StateGraph.SHOW_STATE_INC_TREE", "" + TimedStateGraph.SHOW_STATE_INC_TREE); +//// prop.put("StateGraph.USING_POSET", "" + TimedStateGraph.USING_POSET); +// prop.put("REMOVE_DUMMY", "" + REMOVE_DUMMY); +// prop.put("FIND_FAILURE", "" + FIND_FAILURE); +// prop.put("SHOW_SIGNALS", "" + SHOW_SIGNALS); +// prop.put("SHOW_FAILURES", "" + SHOW_FAILURES); +//// prop.put("Expr.PRINT_DEBUG", "" + Expression.PRINT_DEBUG); +// prop.put("LPNTran.ENABLE_PRINT", "" + LPNTran.ENABLE_PRINT); +// prop.put("LPNTran.PRINT_LEVEL", "" + LPNTran.PRINT_LEVEL); +//// prop.put("Markings.INIT_SIZE", "" + Markings.INIT_SIZE); +// prop.put("OutputDOT.SIMPLE_TRAN_LABELS", "" + OutputDOT.SIMPLE_TRAN_LABELS); +// prop.put("OutputDOT.SIMPLE_STATES", "" + OutputDOT.SIMPLE_STATES); +//// prop.put("StateGraph.LPN_PATH", "" + TimedStateGraph.LPN_PATH); +//// prop.put("StateGraph.DOT_PATH", "" + TimedStateGraph.DOT_PATH); +//// prop.put("StateGraph.TIMED_ANALYSIS", "" + TimedStateGraph.TIMED_ANALYSIS); +//// prop.put("StateGraph.INTERACTIVE_MODE", "" + TimedStateGraph.INTERACTIVE_MODE); +//// prop.put("StateGraph.OPEN_STATE_EXPLORER", "" + TimedStateGraph.OPEN_STATE_EXPLORER); +//// prop.put("StateGraph.DRAW_JAVA_GRAPH", "" + TimedStateGraph.DRAW_JAVA_GRAPH); +//// prop.put("StateGraph.DRAW_MEMORY_GRAPH", "" + TimedStateGraph.DRAW_MEMORY_GRAPH); +//// prop.put("StateGraph.DRAW_STATE_GRAPH", "" + TimedStateGraph.DRAW_STATE_GRAPH); +//// prop.put("StateGraph.OUTPUT_DOT", "" + TimedStateGraph.OUTPUT_DOT); +//// prop.put("StateGraph.STOP_ON_ERROR", "" + TimedStateGraph.STOP_ON_ERROR); +//// prop.put("StateGraph.STOP_ON_FAILURE", "" + TimedStateGraph.STOP_ON_FAILURE); +//// prop.put("StateGraph.PRINT_LEVEL", "" + TimedStateGraph.PRINT_LEVEL); +// prop.put("ZONE_ENABLE_PRINT", "" + ZONE_ENABLE_PRINT); +// prop.put("LPN.ENABLE_PRINT", "" + LPN.ENABLE_PRINT); +// prop.put("NO_DATE", "" + NO_DATE); +// prop.put("PRINT_FINAL_SUMMARY", "" + PRINT_FINAL_SUMMARY); +// prop.put("PRINT_MAIN", "" + PRINT_MAIN); +// prop.put("GRAPH_KEEP_ALIVE_TIME", "" + GRAPH_KEEP_ALIVE_TIME); +// prop.put("MAX_STACK_HEIGHT", "" + MAX_STACK_HEIGHT); +// prop.put("ZONE_OPTIMIZE_INF", "" + ZONE_OPTIMIZE_INF); +// prop.put("ZONE_VERSION", "" + ZONE_VERSION); +// +// try { +// FileOutputStream fos = new FileOutputStream(propFile); +// String str = ""; +// int idx = 0; +// String[] entries = new String[prop.entrySet().size()]; +// for (Entry ent : prop.entrySet()) { +// str = String.format("%-30s = %-1s\n", ent.getKey(), ent.getValue()); +// entries[idx++] = str.replace("\\", "\\\\"); +// } +// +// Arrays.sort(entries); +// fos.write(("\n############ PRINT ##############\n").getBytes()); +// +// for (String ent : entries) { +// if (ent.toLowerCase().contains("print")) { +// fos.write((ent).getBytes()); +// } +// } +// +// fos.write(("\n############ path ##############\n").getBytes()); +// +// for (String ent : entries) { +// if (ent.toLowerCase().contains("print")) continue; +// +// if (ent.toLowerCase().contains("path")) { +// fos.write((ent).getBytes()); +// } +// } +// +// fos.write(("\n############# DOT ###############\n").getBytes()); +// +// for (String ent : entries) { +// if (ent.toLowerCase().contains("print")) continue; +// if (ent.toLowerCase().contains("path")) continue; +// if (ent.toLowerCase().contains("dot")) { +// fos.write((ent).getBytes()); +// } +// } +// +// fos.write(("\n############ GRAPHS #############\n").getBytes()); +// +// for (String ent : entries) { +// if (ent.toLowerCase().contains("print")) { +// continue; +// } +// if (ent.toLowerCase().contains("path")) { +// continue; +// } +// if (ent.toLowerCase().contains("dot")) { +// continue; +// } +// if (ent.toLowerCase().contains("graph")) { +// fos.write((ent).getBytes()); +// } +// } +// +// fos.write(("\n############ OTHER ##############\n").getBytes()); +// +// for (String ent : entries) { +// if (ent.toLowerCase().contains("print")) { +// continue; +// } +// if (ent.toLowerCase().contains("path")) { +// continue; +// } +// if (ent.toLowerCase().contains("dot")) { +// continue; +// } +// if (ent.toLowerCase().contains("graph")) { +// continue; +// } +// fos.write((ent).getBytes()); +// } +// fos.close(); +// } catch (IOException e) { +// e.printStackTrace(); +// } catch (NullPointerException e) { +// e.printStackTrace(); +// } +// return prop; +// } + + public static String mergeColumns(String a, String b, int w1, int w2) { + String ret = ""; + StringTokenizer tk1 = new StringTokenizer(a, "\n"); + StringTokenizer tk2 = new StringTokenizer(b, "\n"); + while (tk1.hasMoreTokens() && tk2.hasMoreTokens()) { + ret += String.format("%-" + w1 + "s | %-" + w2 + "s |\n", tk1.nextToken(), tk2.nextToken()); + } + while (tk2.hasMoreTokens()) { + ret += String.format("%-" + w1 + "s | %-" + w2 + "s |\n", "", tk2.nextToken()); + } + while (tk1.hasMoreTokens()) { + ret += String.format("%-" + w1 + "s | %-" + w2 + "s |\n", tk1.nextToken(), ""); + } + return ret; + } + + public static String mergeColumns(String a, String b, String c, int w1, int w2, int w3) { + String ret = ""; + StringTokenizer tk1 = new StringTokenizer(a, "\n"); + StringTokenizer tk2 = new StringTokenizer(b, "\n"); + StringTokenizer tk3 = new StringTokenizer(c, "\n"); + String s1 = null, s2 = null, s3 = null; + while (tk1.hasMoreTokens() || tk2.hasMoreTokens() || tk3.hasMoreTokens()) { + s1 = tk1.hasMoreTokens() ? tk1.nextToken() : ""; + s2 = tk2.hasMoreTokens() ? tk2.nextToken() : ""; + s3 = tk3.hasMoreTokens() ? tk3.nextToken() : ""; + ret += String.format("%-" + w1 + "s | %-" + w2 + "s | %-" + w3 + "s |\n", + s1,// (""+s1).replace("\t", "...").replace(" ", "~"), + s2,// (""+s2).replace("\t", "...").replace(" ", "~"), + s3// (""+s3).replace("\t", "...").replace(" ", "~") + ); + } + return ret; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/main/Options.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/main/Options.java new file mode 100644 index 000000000..691919449 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/main/Options.java @@ -0,0 +1,523 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.main; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Options { + /* + * Levels given by an integer number to indicate the amount information to display + * while the tool is running + */ + private static int verbosity = 0; + + /* + * Path in the host where the DOT program is located + */ + private static String dotPath = System.getProperty("user.dir"); + + /* + * Timing analysis options: + */ + public static enum timingAnalysisDef { + ON, // no timing; zone - use regular zones; + ABSTRACTION // merge zones to form convex hull for the same untimed state. + } + private static String timingAnalysisType = "off"; + + // Hao's Partial Order reduction options. +// /* +// * Partial order reduction options +// */ +// public static enum PorDef { +// OFF, // no POR +// STATIC, // POR based on dependency relation by static analysis +// BEHAVIORAL // POR based on dependency relation by behavioral analysis +// }; +// private static String POR = "off"; + + /** + * Partial order reduction options for ample set computation (not including ample computation for cycle closing check). + * @author Zhen Zhang + * + */ + public static enum PorDef { + TB, // POR with trace-back + TBOFF, // POR without trace-back + BEHAVIORAL, // POR with behavioral analysis + OFF // No POR + } + private static String POR = "off"; + + + /** + * Options for dealing with transition rates when partial order reduction is applied. + * @author Zhen Zhang + */ + public static enum tranRatePorDef { + FULL, // Fully consider dependency relations in transition rates + AVRG, // Add a second criterion for persistent set computation. When more than one persistent sets have the smallest size, + // choose one that has higher average transition rates. + TOLR, // Only consider transition rate dependency when the rate change exceeds some tolerance + NONE, // Ignore entirely the dependency relations in transition rates. + } + private static String tranRatePorDef = "full"; + + /* + * Cycle closing method for partial order reduction + */ + public static enum cycleClosingMethdDef{ + BEHAVIORAL, // Improved behavioral analysis on cycle closing + STATE_SEARCH, // Improved behavioral analysis + state trace-back + NO_CYCLECLOSING, // no cycle closing, generated SG may not be valid. + STRONG, // Strong cycle condition: for each cycle, at least one state has to fully expand. + } + private static String cycleClosingMethd = "behavioral"; + + /* + * Ample computation during cycle closing check. + */ + public static enum cycleClosingStrongStubbornMethdDef { + CCTB, // cycle closing with trace-back + CCTBDG, // cycle closing with trace-back using dependency graphs + CCTBOFF // cycle closing without trace-back + } + private static String cycleClosingStrongStubbornMethd = "cctb"; +//// /* +//// * Flag to use use dependent set queue for POR +//// */ +// private static boolean useDependentQueue = false; + + /* + * Report disabling error flag + */ + private static boolean disablingError = true; + + /* + * Output state graph (dot) flag + */ + private static boolean outputSgFlag = false; + + /* + * Debug mode : options to print intermediate results during POR + */ + private static boolean debug = false; + + /* + * Option for printing final numbers from search_dfs or search_dfsPOR. + */ + private static boolean outputLogFlag = false; + + /* + * Name of the LPN under verification. + */ + private static String lpnName = null; + + /* + * Path for printing global state graph + */ + private static String prjSgPath = null; + + /* + * Flag indate if there is a user specified memory upper bound + */ + private static boolean memoryUpperBoundFlag; + + /* + * User specified memory upper bound + */ + private static long memoryUpperBound; + + /* + * Search algorithm options: + */ + public static enum searchTypeDef { + DFS, // DFS search on the entire state space + BFS, // BFS on the entire state space. + COMPOSITIONAL // using compositional search/reduction to build the reduce SG. + } + + private static String searchType = "dfs"; + + /* + * Options on how reachable states are stored. + */ + public static enum StateFormatDef { + EXPLICIT, // hash tables in java + MDDBUF, // Mutli-Value DD + MDD, // Mutli-Value DD + BDD, // BDD + AIG, // AIG + BINARY_TREE, // Binary tree + DECOMPOSED, // decompose a global state into a set of triples of global vectors and two local states sharing variables. + NATIVE_HASH // hash table in C/C++ + } + private static String stateFormat = "explicit"; + + /* + * Use multi-threading when set to true. + */ + private static boolean parallelFlag = false; + + /* + * Memory upper bound for a verification run. The unit is MB. + */ + public static int MemUpperBound = 1800; + + /* + * Upper bound on the total runtime for a run. The unit is in seconds. + */ + public static int TimeUpperBound = 1500; + + /* The timing log file */ + public static String _TimingLogFile = null; + + /* Sets the _TimingLogFile */ + public static void set_TimingLogFile(String logFile){ + _TimingLogFile = logFile; + } + + /* Gets the _TimingLogFile */ + public static String get_TimingLogfile(){ + return _TimingLogFile; + } + + /* Flag for range of resets after transitions alone*/ + public static boolean _resetOnce = false; + + /* Sets the _resetOnce flag. */ + public static void set_resetOnce(boolean resetOnce){ + _resetOnce = resetOnce; + } + + /* Gets the _resetOnce flag. */ + public static boolean get_resetOnce(){ + return _resetOnce; + } + + /* Flag for turning on rate event optimization*/ + private static boolean _rateOptimization = false; + + /* Sets the _rateOptimization flag. */ + public static void set_rateOptimization(Boolean rateOptimization){ + _rateOptimization = rateOptimization; + } + + /* Gets the _rateOptimization flag. */ + public static Boolean get_rateOptimization(){ + return _rateOptimization; + } + + /* + * Flag for turn on/off the gui response for + * verification results + */ + private static boolean _displayResults = false; + + /* Sets the _displayResults flag. */ + public static void set_displayResults(boolean displayResults){ + _displayResults = displayResults; + } + + /* Gets the _displayResults flag. */ + public static boolean get_displayResults(){ + return _displayResults; + } + + /* + * Flag for turning on/off showing the DBM + * as part of the state graph. + */ + private static boolean _displayDBM; + + /* Sets the _displayDBM flag. */ + public static void set_displayDBM(boolean displayDBM){ + _displayDBM = displayDBM; + } + + /* Gets the _displayDBM flag. */ + public static boolean get_displayDBM(){ + return _displayDBM; + } + + /* + * Option for compositional minimization type. + * off - no state space reduction + * abstraction - transition based abstraction + * reduction - state space reduction + */ + private static String compositionalMinimization = "off"; + + private static boolean newParser = false; + + /* + * When true, use non-disabling semantics for transition firing. + */ + private static boolean stickySemantics = false; + private static boolean timingAnalysisFlag = false; + + /** + * When true, Markovian analysis can be applied to the LPN model. + */ + private static boolean markovianModel = false; + + public static void setCompositionalMinimization(String minimizationType){ + if (minimizationType.equals("abstraction")){ + compositionalMinimization = minimizationType; + } + else if (minimizationType.equals("reduction")){ + compositionalMinimization = minimizationType; + } + else if (minimizationType.equals("off")){ + + } + else{ + System.out.println("warning: invalid COMPOSITIONAL_MINIMIZATION option - default is \"off\""); + } + } + + public static String getCompositionalMinimization(){ + return compositionalMinimization; + } + + public static boolean getTimingAnalysisFlag(){ + return timingAnalysisFlag; + } + + public static void setStickySemantics(){ + stickySemantics = true; + } + + public static boolean getStickySemantics(){ + return stickySemantics; + } + + public static void setVerbosity(int v){ + verbosity = v; + } + + public static int getVerbosity(){ + return verbosity; + } + + public static void setDotPath(String path){ + dotPath = path; + } + + public static String getDotPath(){ + return dotPath; + } + + public static void setTimingAnalsysisType(String timing){ + if (timing.equals("zone")){ + timingAnalysisFlag = true; + timingAnalysisType = timing; + } + else if (timing.equals("octagon")){ + timingAnalysisFlag = true; + timingAnalysisType = timing; + } + else if (timing.equals("poset")){ + timingAnalysisFlag = true; + timingAnalysisType = timing; + } + else if (timing.equals("off")){ + // Alteration by Andrew N. Fisher + timingAnalysisFlag = false; + timingAnalysisType = "off"; + } + else{ + System.out.println("warning: invalid TIMING_ANALYSIS option - default is \"off\""); + } + } + + public static String getTimingAnalysisType(){ + return timingAnalysisType; + } + + public static void setPOR(String por){ + POR = por; + } + + public static String getPOR(){ + return POR; + } + + public static void setSearchType(String type){ + searchType = type; + } + + public static String getSearchType(){ + return searchType; + } + + public static void setStateFormat(String format){ + if (format.equals("explicit")){ + + } + else if (format.equals("bdd")){ + stateFormat = format; + } + else if (format.equals("aig")){ + stateFormat = format; + } + else if (format.equals("mdd")){ + stateFormat = format; + } + else if (format.equals("mddbuf")){ + stateFormat = format; + } + else{ + System.out.println("warning: invalid STATE_FORMAT option - default is \"explicit\""); + } + } + + public static String getStateFormat(){ + return stateFormat; + } + + public static void setParallelFlag(){ + parallelFlag = true; + } + + public static boolean getParallelFlag(){ + return parallelFlag; + } + + public static void setNewParser(){ + newParser = true; + } + + public static boolean getNewParser(){ + return newParser; + } + + public static void setCycleClosingMthd(String cycleclosing) { + cycleClosingMethd = cycleclosing; + } + + public static String getCycleClosingMthd() { + return cycleClosingMethd; + } + + public static void setOutputSgFlag(boolean outputSGflag) { + outputSgFlag = outputSGflag; + } + + public static boolean getOutputSgFlag() { + return outputSgFlag; + } + + public static void setPrjSgPath(String path) { + prjSgPath = path; + } + public static String getPrjSgPath() { + return prjSgPath; + } + + public static void setCycleClosingStrongStubbornMethd(String method) { + cycleClosingStrongStubbornMethd = method; + } + + public static String getCycleClosingStrongStubbornMethd() { + return cycleClosingStrongStubbornMethd; + } + + public static void setDebugMode(boolean debugMode) { + debug = debugMode; + } + + public static boolean getDebugMode() { + return debug; + } + + public static void setOutputLogFlag(boolean printLog) { + outputLogFlag = printLog; + } + + public static boolean getOutputLogFlag() { + return outputLogFlag; + } + + public static void setLogName(String logName) { + lpnName = logName; + } + + public static String getLogName() { + return lpnName; + } + +// public static void disablePORdeadlockPreserve() { +// porDeadlockPreserve = false; +// } +// public static boolean getPORdeadlockPreserve() { +// return porDeadlockPreserve; +// } + + public static void disableDisablingError() { + disablingError = false; + } + + public static boolean getReportDisablingError() { + return disablingError; + } + + public static void setMemoryUpperBound(long value) { + memoryUpperBound = value; + } + public static float getMemUpperBound() { + return memoryUpperBound; + + } + + public static void setMemUpperBoundFlag() { + memoryUpperBoundFlag = true; + } + + public static boolean getMemUpperBoundFlag() { + return memoryUpperBoundFlag; + } + +// public static boolean getUseDependentQueue() { +// return useDependentQueue; +// } +// +// public static boolean setUseDependentQueue() { +// return useDependentQueue = true; +// } + + public static void setMarkovianModelFlag() { + markovianModel = true; + } + + public static boolean getMarkovianModelFlag() { + return markovianModel; + } + + public static String getTranRatePorDef() { + return tranRatePorDef; + } + + public static void setTranRatePorDef(String tranRatePorDef) { + Options.tranRatePorDef = tranRatePorDef; + } + + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/MarkovianAnalysis.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/MarkovianAnalysis.java new file mode 100644 index 000000000..036f1b9f1 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/MarkovianAnalysis.java @@ -0,0 +1,1177 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.markovianAnalysis; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Queue; + +import javax.swing.JProgressBar; + +import edu.utah.ece.async.ibiosim.dataModels.util.dataparser.DataParser; +import edu.utah.ece.async.ibiosim.dataModels.util.exceptions.BioSimException; +import edu.utah.ece.async.lema.verification.lpn.ExprTree; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.lpn.Translator; +import edu.utah.ece.async.lema.verification.platu.project.PrjState; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class MarkovianAnalysis implements Runnable{ + + private boolean stop; + private DataParser probData; + private int waitingThreads, threadCount; + private boolean phase1, phase2; + /** + * This list includes names for all variables created during analysis of nested probability + * (name format: "Pr" + nestedPropString.hashCode() or "St" + nestedPropString.hashCode() + */ + private ArrayList nestedProbIDs; + /** + * This list includes the names of all LPN discrete (integer) variables. + * Variables that are created during analysis of nested properties will be added to this list too. + */ + private ArrayList varNameList; + + private ProbGlobalStateSet globalStateSet; + + + public MarkovianAnalysis(ProbGlobalStateSet globalStateSet) { + this.globalStateSet = globalStateSet; + varNameList = new ArrayList(); + for (State initLocal : this.globalStateSet.getInitialState().toStateArray()) { + for (String intVarName : initLocal.getLpn().getIntVars()) + if (!varNameList.contains(intVarName)) + varNameList.add(intVarName); + } + } + + public boolean performSteadyStateMarkovianAnalysis(double tolerance, ArrayList props, + PrjState initial, JProgressBar progress) throws BioSimException { + // Moved the test to perform Markovian analysis to the run method in Verification.java, where LPN(s) are loaded + // or generated from decomposition. + ArrayList conditions = new ArrayList(); + if (props != null) { + for (Property p : props) { + if (p.getProperty().substring(5, p.getProperty().length() - 1).contains("St=?{") + || p.getProperty().substring(5, p.getProperty().length() - 1).contains("Pr=?{")) { + conditions.add(createProperty( + p.getLabel(), + removeNesting(tolerance, 100, p.getProperty() + .substring(5, p.getProperty().length() - 1), progress))); + } + else { + conditions.add(p); + } + } + } + if (progress != null) { + progress.setString(null); + progress.setIndeterminate(true); + } + //enableAllTransitions(); + setAllGlobalStatesAsNonAbsorbing(); + // -------------------- + boolean change = false; + boolean converged = false; + int counter = 0; + computeTransitionRateSum(); + // Set initial probability and period for all global states. + if (!stop) { + for (PrjState m : globalStateSet.keySet()) { + ((ProbGlobalState) m).setCurrentProb(0.0); + } + ((ProbGlobalState) initial).setCurrentProb(1.0); + } + resetColorsForMarkovianAnalysis(); + int period = findPeriod(initial); + System.out.println("period = " + period); + if (period == 0) { + period = 1; + } + while (!converged && !stop) { + counter++; + counter = counter % period; + for (PrjState curGlobalSt : globalStateSet.keySet()) { +// for (Transition outTran : ((ProbGlobalState) curGlobalSt).getOutgoingTranSetForProbGlobalState()) { +// PrjState nextGlobalSt = ((ProbGlobalState) curGlobalSt).getNextGlobalState(outTran); + for (Transition outTran : curGlobalSt.getNextGlobalStateMap().keySet()) { + PrjState nextGlobalSt = curGlobalSt.getNextGlobalStateMap().get(outTran); + double curStCurProb = ((ProbGlobalState) curGlobalSt).getCurrentProb(); + if (curStCurProb > 0.0) { + double nextStNextProb = ((ProbGlobalState) nextGlobalSt).getNextProb(); + double tranProb = ((ProbGlobalState) curGlobalSt).getTranProb(outTran); + ((ProbGlobalState) nextGlobalSt).setNextProb(nextStNextProb + curStCurProb * tranProb); + } + } + if (stop) { + return false; + } + } + for (PrjState globalSt : globalStateSet.keySet()) { + if (((ProbGlobalState) globalSt).getColor() == counter) { + double nextProb = ((ProbGlobalState) globalSt).getNextProb(); + double piProb = ((ProbGlobalState) globalSt).getPiProb(); + if (Math.abs((nextProb - piProb)/nextProb) > tolerance) + change = true; + ((ProbGlobalState) globalSt).setPiProb(nextProb); + } + ((ProbGlobalState) globalSt).setCurrentProbToNext(); + ((ProbGlobalState) globalSt).setNextProb(0.0); + if (stop) { + return false; + } + } + if (counter == 0) { + if (!change) + converged = true; + change = false; + } + } + for (PrjState curGlobalSt : globalStateSet.keySet()) { + ((ProbGlobalState) curGlobalSt).setPiProb(0.0); + } + for (int i=0; i 1) { +// System.out.println(curGlobalSt.getLabel() + ", curProb = " +// + ((ProbGlobalState) curGlobalSt).getCurrentProb() + ", exceeds 1."); +// //System.exit(1); +// //return; +// } +// if (((ProbGlobalState) curGlobalSt).getNextProb() > 1) { +// System.out.println(curGlobalSt.getLabel() + ", nextProb = " +// + ((ProbGlobalState) curGlobalSt).getNextProb() + ", exceeds 1."); +// //System.exit(1); +// //return; +// } +// if (((ProbGlobalState) curGlobalSt).getPiProb() > 1) { +// System.out.println(curGlobalSt.getLabel() + ", piProb = " +// + ((ProbGlobalState) curGlobalSt).getPiProb() + ", exceeds 1."); +// //System.exit(1); +// //return; +// } +// System.out.println(curGlobalSt.getLabel() +// + ",\t curProb = " + ((ProbGlobalState) curGlobalSt).getCurrentProb() +// + ",\t nextProb = " + ((ProbGlobalState) curGlobalSt).getNextProb() +// + ",\t piProb = " + ((ProbGlobalState) curGlobalSt).getPiProb()); +// } +// System.out.println("------------------------------------------------------------------------"); +// } + + private void computeTransitionRateSum() { + //System.out.println("--------------- Transition Rate Sum -------------"); + for (PrjState curGlobalSt : globalStateSet.keySet()) { + ((ProbGlobalState) curGlobalSt).computeTranRateSum(); + //System.out.println(curGlobalSt.getLabel() + ", tranRateSum = " + ((ProbGlobalState) curGlobalSt).getTranRateSum()); + } + } + + private void resetColorsForMarkovianAnalysis() { + for (PrjState m : globalStateSet.keySet()) { + ((ProbGlobalState) m).setColor(-1); + if (stop) { + return; + } + } + } + + private int findPeriod(PrjState curSt) { + if (stop) { + return 0; + } + int period = 0; + int color = 0; + ((ProbGlobalState) curSt).setColor(color); + color = ((ProbGlobalState) curSt).getColor() + 1; + Queue unVisitedStates = new LinkedList(); + //for (PrjState nextSt : ((ProbGlobalState) curSt).getNextProbGlobalStateSet(globalStateSet)) { + for (PrjState nextSt : curSt.getNextGlobalStateMap().values()) { + if (((ProbGlobalState) nextSt).getColor() == -1) { + ((ProbGlobalState) nextSt).setColor(color); + unVisitedStates.add(nextSt); + } + else { + if (period == 0) { + period = ((ProbGlobalState) curSt).getColor() - ((ProbGlobalState) nextSt).getColor() + 1; + } + else { + period = gcd(((ProbGlobalState) curSt).getColor() - ((ProbGlobalState) nextSt).getColor() + 1, period); + } + } + if (stop) { + return 0; + } + } + while (!unVisitedStates.isEmpty() && !stop) { + curSt = unVisitedStates.poll(); + color = ((ProbGlobalState) curSt).getColor() + 1; + //for (PrjState nextSt : ((ProbGlobalState)curSt).getNextProbGlobalStateSet(globalStateSet)) { + for (PrjState nextSt : curSt.getNextGlobalStateMap().values()) { + if (((ProbGlobalState) nextSt).getColor() == -1) { + ((ProbGlobalState) nextSt).setColor(color); + unVisitedStates.add(nextSt); + } + else { + if (period == 0) { + period = (((ProbGlobalState) curSt).getColor() - ((ProbGlobalState) nextSt).getColor() + 1); + } + else { + period = gcd(((ProbGlobalState) curSt).getColor() - ((ProbGlobalState) nextSt).getColor() + 1, period); + } + } + if (stop) { + return 0; + } + } + } + return period; + } + + private int gcd(int a, int b) { + if (b == 0) + return a; + return gcd(b, a % b); + } + + //private String removeNesting(double error, double timeStep, String prop, JProgressBar progress) { + private String removeNesting(double error, double timeStep, String prop, JProgressBar progress) throws BioSimException { + if (prop.contains("Pr=?{") || prop.contains("St=?{")) { + if (progress != null) { + progress.setString("Determining Sat Sets."); + } + int transientPropIndex = prop.indexOf("Pr=?{"); + int steadyStatePropIndex = prop.indexOf("St=?{"); + if (transientPropIndex == -1) { + transientPropIndex = Integer.MAX_VALUE; + } + if (steadyStatePropIndex == -1) { + steadyStatePropIndex = Integer.MAX_VALUE; + } + int index = 0; + if (transientPropIndex < steadyStatePropIndex) { + index = transientPropIndex; + } + else { + index = steadyStatePropIndex; + } + String newProp = prop.substring(0, index); + String cond = prop.substring(index); + String nest; + if (transientPropIndex < steadyStatePropIndex) { + nest = "Pr=?{"; + } + else { + nest = "St=?{"; + } + int braces = 1; + for (int i = 5; i < cond.length(); i++) { + char c = cond.charAt(i); + if (c == '{') { + braces++; + } + else if (c == '}') { + braces--; + } + nest += c; + index = i; + if (braces == 0) { + break; + } + } + index++; + cond = cond.substring(index); + String check = nest.substring(5, nest.length() - 1); + if (check.contains("Pr=?{") || check.contains("St=?{")) { + if (transientPropIndex < steadyStatePropIndex) { + nest = "Pr=?{" + removeNesting(error, timeStep, check, progress) + "}"; + } + else { + nest = "St=?{" + removeNesting(error, timeStep, check, progress) + "}"; + } + } + newProp += determineNestedProbability(error, timeStep, nest) + + removeNesting(error, timeStep, cond, progress); + return newProp; + } + return prop; + } + + private String determineNestedProbability(double error, double timeStep, String property) throws BioSimException { + String prop = ""; + int braces = 0; + for (int i = 0; i < property.length(); i++) { + char c = property.charAt(i); + if (c == '{') { + braces++; + } + else if (c == '}') { + braces--; + } + if (braces == 1) { + if ((c == 'G' || c == 'F' || c == 'U') && property.charAt(i + 1) == '[') { + prop += "P" + c; + } + else { + prop += c; + } + } + else { + prop += c; + } + } + String[] condition = Translator.getProbpropParts(prop.substring(5, prop.length() - 1)); + String id = "Pr" + Math.abs(prop.hashCode()); + if (!this.nestedProbIDs.contains(id)) { + nestedProbIDs.add(id); + boolean globallyTrue = false; + if (prop.contains("PF")) { + condition[0] = "true"; + } + else if (prop.contains("PG")) { + condition[0] = "true"; + globallyTrue = true; + } + for (PrjState initial : globalStateSet.keySet()) { + // Previously, we checked if (!this.nestedProbIDs.contains(id)) already. +// if (((ProbGlobalState) initial).getNestedProbValues().keySet().contains(id)) { +// break; +// } + //enableAllTransitions(); + setAllGlobalStatesAsNonAbsorbing(); + double Gamma; + for (PrjState m : globalStateSet.keySet()) { + ((ProbGlobalState) m).setCurrentProb(0.0); + ((ProbGlobalState) m).setPiProb(0.0); + } + ((ProbGlobalState) initial).setCurrentProb(1.0); + ((ProbGlobalState) initial).setPiProb(1.0); + double lowerbound = 0; + if (!condition[2].equals("")) { + ExprTree expr = new ExprTree(varNameList); + expr.token = expr.intexpr_gettok(condition[2]); + expr.intexpr_L(condition[2]); + lowerbound = expr.evaluateExpr(null); + pruneStateGraph("~(" + condition[0] + ")"); + // Compute Gamma + Gamma = 0; + for (PrjState m : globalStateSet) { + //Gamma = Math.max(m.getTransitionSum(0.0, null), Gamma); + Gamma = Math.max(((ProbGlobalState) m).getTranRateSum(), Gamma); + } + // Compute K + int K = 0; + double xi = 1; + double delta = 1; + double eta = (1 - error) / (Math.pow(Math.E, ((0 - Gamma) * timeStep))); + while (delta < eta) { + K = K + 1; + xi = xi * ((Gamma * timeStep) / K); + delta = delta + xi; + } + double step = Math.min(timeStep, lowerbound); + for (double i = 0; i < lowerbound; i += step) { + step = Math.min(timeStep, lowerbound - i); + if (step != timeStep) { + // Compute K + K = 0; + xi = 1; + delta = 1; + eta = (1 - error) / (Math.pow(Math.E, ((0 - Gamma) * step))); + while (delta < eta) { + K = K + 1; + xi = xi * ((Gamma * step) / K); + delta = delta + xi; + } + } + performTransientMarkovianAnalysis(step, Gamma, K, null); + } + } + else { + pruneStateGraph("~(" + condition[0] + ")"); + } + double upperbound; + if (condition[3].equals("inf")) { + upperbound = -1; + } + else { + ExprTree expr = new ExprTree(varNameList); + expr.token = expr.intexpr_gettok(condition[3]); + expr.intexpr_L(condition[3]); + upperbound = expr.evaluateExpr(null) - lowerbound; + } + if (globallyTrue) { + pruneStateGraph("~(" + condition[1] + ")"); + } + else { + pruneStateGraph(condition[1]); + } + if (upperbound == -1) { + ArrayList conditions = new ArrayList(); + if (!condition[0].equals("true")) { + conditions.add(new Property("Failure", "~(" + condition[0] + ")&~(" + condition[1] + ")")); + } + else { + conditions.add(new Property("Failure", "~(" + condition[1] + ")")); + } + conditions.add(new Property("Success", condition[1])); + performSteadyStateMarkovianAnalysis(error, conditions, initial, null); + } + // Compute Gamma + Gamma = 0; + for (PrjState m : globalStateSet) { + Gamma = Math.max(((ProbGlobalState) m).getTranRateSum(), Gamma); + } + // Compute K + int K = 0; + double xi = 1; + double delta = 1; + double eta = (1 - error) / (Math.pow(Math.E, ((0 - Gamma) * timeStep))); + while (delta < eta) { + K = K + 1; + xi = xi * ((Gamma * timeStep) / K); + delta = delta + xi; + } + double step = Math.min(timeStep, upperbound - lowerbound); + for (double i = 0; i < upperbound; i += step) { + step = Math.min(timeStep, upperbound - i); + if (step != timeStep) { + // Compute K + K = 0; + xi = 1; + delta = 1; + eta = (1 - error) / (Math.pow(Math.E, ((0 - Gamma) * step))); + while (delta < eta) { + K = K + 1; + xi = xi * ((Gamma * step) / K); + delta = delta + xi; + } + } + performTransientMarkovianAnalysis(step, Gamma, K, null); + } + //double failureProb = 0; + //double timelimitProb = 0; + double successProb = 0; + for (PrjState m : globalStateSet) { + // for (String state : stateGraph.keySet()) { + // for (State m : stateGraph.get(state)) { + ExprTree failureExpr = new ExprTree(varNameList); + failureExpr.token = failureExpr.intexpr_gettok("~(" + condition[0] + ")&~(" + condition[1] + ")"); + failureExpr.intexpr_L("~(" + condition[0] + ")&~(" + condition[1] + ")"); + ExprTree successExpr = new ExprTree(varNameList); + if (globallyTrue) { + successExpr.token = successExpr.intexpr_gettok("~(" + condition[1] + ")"); + successExpr.intexpr_L("~(" + condition[1] + ")"); + } + else { + successExpr.token = successExpr.intexpr_gettok(condition[1]); + successExpr.intexpr_L(condition[1]); + } + if (successExpr.evaluateExpr(((ProbGlobalState) m).getVariables()) == 1.0) { + successProb += ((ProbGlobalState) m).getCurrentProb(); + } +// if (failureExpr.evaluateExpr(m.getVariables()) == 1.0) { +// failureProb += m.getCurrentProb(); +// } +// else if (successExpr.evaluateExpr(m.getVariables()) == 1.0) { +// successProb += m.getCurrentProb(); +// } +// else { +// if (!globallyTrue) { +// timelimitProb += m.getCurrentProb(); +// } +// } + // } + } + if (globallyTrue) { + successProb = 1 - successProb; + //timelimitProb = 1 - (failureProb + successProb); + } + ((ProbGlobalState) initial).addNestedProb(id, "" + successProb); + } + } + return id; + } + + public static Property createProperty(String label, String property) { + return new Property(label, property); + } + + public boolean performTransientMarkovianAnalysis(double timeLimit, double timeStep, double printInterval, + double error, String[] condition, JProgressBar progress, boolean globallyTrue) throws BioSimException { + // Moved the test for the ability to perform Markovian analysis to the run method in Verification.java, + // where LPN(s) are loaded or generated from decomposition. + computeTransitionRateSum(); + if (condition != null) { + condition[0] = removeNesting(error, timeStep, condition[0], progress); + condition[1] = removeNesting(error, timeStep, condition[1], progress); + progress.setString(null); + double nextPrint = printInterval; + if (condition[3].equals("inf")) { + progress.setIndeterminate(true); + } + else { + ExprTree expr = new ExprTree(varNameList); + expr.token = expr.intexpr_gettok(condition[3]); + expr.intexpr_L(condition[3]); + progress.setMaximum((int) expr.evaluateExpr(null)); + } + //enableAllTransitions(); + setAllGlobalStatesAsNonAbsorbing(); + ProbGlobalState initial = (ProbGlobalState) globalStateSet.getInitialState(); + if (initial != null) { + for (PrjState m : globalStateSet.keySet()) { + ((ProbGlobalState) m).setCurrentProb(0.0); + ((ProbGlobalState) m).setPiProb(0.0); + } + initial.setCurrentProb(1.0); + initial.setPiProb(1.0); + } + double lowerbound = 0; + if (!condition[2].equals("")) { + ExprTree expr = new ExprTree(varNameList); + expr.token = expr.intexpr_gettok(condition[2]); + expr.intexpr_L(condition[2]); + // lowerbound = Math.min(expr.evaluateExpr(null), timeLimit); + lowerbound = expr.evaluateExpr(null); + } + double Gamma; + ArrayList dataLabels = new ArrayList(); + dataLabels.add("time"); + // dataLabels.add("~(" + condition[0] + ")&~(" + condition[1] + + // ")"); + dataLabels.add("Failure"); + // dataLabels.add(condition[1]); + dataLabels.add("Success"); + ArrayList> data = new ArrayList>(); + ArrayList temp = new ArrayList(); + temp.add(0.0); + data.add(temp); + temp = new ArrayList(); + double failureProb = 0; + for (PrjState m : globalStateSet.keySet()) { + ExprTree failureExpr = new ExprTree(varNameList); + if (lowerbound == 0) { + if (!condition[0].equals("true")) { + failureExpr.token = failureExpr.intexpr_gettok("~(" + condition[0] + ")&~(" + condition[1] + + ")"); + failureExpr.intexpr_L("~(" + condition[0] + ")&~(" + condition[1] + ")"); + } + } + else if (!condition[0].equals("true")) { + failureExpr.token = failureExpr.intexpr_gettok("~(" + condition[0] + ")"); + failureExpr.intexpr_L("~(" + condition[0] + ")"); + } + if (failureExpr.evaluateExpr(((ProbGlobalState) m).getVariables()) == 1.0) { + failureProb += ((ProbGlobalState) m).getCurrentProb(); + } + } + temp.add(failureProb * 100); + data.add(temp); + // if (globallyTrue) { + double successProb = 0; + if (lowerbound == 0) { + for (PrjState m : globalStateSet.keySet()) { + ExprTree successExpr = new ExprTree(varNameList); + successExpr.token = successExpr.intexpr_gettok(condition[1]); + successExpr.intexpr_L(condition[1]); + if (successExpr.evaluateExpr(((ProbGlobalState) m).getVariables()) == 1.0) { + successProb += ((ProbGlobalState) m).getCurrentProb(); + } + } + } + temp = new ArrayList(); + temp.add(successProb * 100); + data.add(temp); + probData = new DataParser(dataLabels, data); + if (initial != null) { + if (!condition[2].equals("")) { + if (!condition[0].equals("true")) { + pruneStateGraph("~(" + condition[0] + ")"); + } + // Compute Gamma + Gamma = 0; + for (PrjState m : globalStateSet.keySet()) + Gamma = Math.max(((ProbGlobalState) m).getTranRateSum(), Gamma); + // Compute K + int K = 0; + double xi = 1; + double delta = 1; + double eta = (1 - error) / (Math.pow(Math.E, ((0 - Gamma) * timeStep))); + while (delta < eta) { + K = K + 1; + xi = xi * ((Gamma * timeStep) / K); + delta = delta + xi; + } + double step = Math.min(Math.min(timeStep, lowerbound), nextPrint); + for (double i = 0; i < lowerbound; i += step) { + step = Math.min(Math.min(timeStep, lowerbound - i), nextPrint - i); + if (step != timeStep) { + // Compute K + K = 0; + xi = 1; + delta = 1; + eta = (1 - error) / (Math.pow(Math.E, ((0 - Gamma) * step))); + while (delta < eta) { + K = K + 1; + xi = xi * ((Gamma * step) / K); + delta = delta + xi; + } + } + if (!performTransientMarkovianAnalysis(step, Gamma, K, progress)) { + return false; + } + double prob = 0; + for (PrjState m : globalStateSet.keySet()) { + ExprTree expr = new ExprTree(varNameList); + expr.token = expr.intexpr_gettok("~(" + condition[0] + ")"); + expr.intexpr_L("~(" + condition[0] + ")"); + if (expr.evaluateExpr(((ProbGlobalState) m).getVariables()) == 1.0) { + prob += ((ProbGlobalState) m).getCurrentProb(); + } + // } + } + if (i + step == nextPrint) { + probData.getData().get(0).add(nextPrint); + probData.getData().get(1).add(prob * 100); + probData.getData().get(2).add(0.0); + nextPrint += printInterval; + } + } + } + else { + if (!condition[0].equals("true")) { + pruneStateGraph("~(" + condition[0] + ")"); + } + } + double upperbound; + if (condition[3].equals("inf")) { + upperbound = -1; + } + else { + ExprTree expr = new ExprTree(varNameList); + expr.token = expr.intexpr_gettok(condition[3]); + expr.intexpr_L(condition[3]); + // upperbound = Math.min(expr.evaluateExpr(null) - + // lowerbound, timeLimit - lowerbound); + upperbound = expr.evaluateExpr(null) - lowerbound; + } + if (globallyTrue) { + pruneStateGraph("~(" + condition[1] + ")"); + } + else { + pruneStateGraph(condition[1]); + } + if (upperbound == -1) { + ArrayList conditions = new ArrayList(); + if (!condition[0].equals("true")) { + conditions.add(new Property("Failure", "~(" + condition[0] + ")&~(" + condition[1] + ")")); + } + else { + conditions.add(new Property("Failure", "~(" + condition[1] + ")")); + } + conditions.add(new Property("Success", condition[1])); + return performSteadyStateMarkovianAnalysis(error, conditions, initial, progress); + } + // Compute Gamma + Gamma = 0; + for (PrjState m : globalStateSet.keySet()) + Gamma = Math.max(((ProbGlobalState) m).getTranRateSum(), Gamma); + // Compute K + int K = 0; + double xi = 1; + double delta = 1; + double eta = (1 - error) / (Math.pow(Math.E, ((0 - Gamma) * timeStep))); + while (delta < eta) { + K = K + 1; + xi = xi * ((Gamma * timeStep) / K); + delta = delta + xi; + } + double step = Math.min(Math.min(timeStep, upperbound - lowerbound), nextPrint - lowerbound); + for (double i = 0; i < upperbound; i += step) { + step = Math.min(Math.min(timeStep, upperbound - i), nextPrint - lowerbound - i); + if (step != timeStep) { + // Compute K + K = 0; + xi = 1; + delta = 1; + eta = (1 - error) / (Math.pow(Math.E, ((0 - Gamma) * step))); + while (delta < eta) { + K = K + 1; + xi = xi * ((Gamma * step) / K); + delta = delta + xi; + } + } + if (!performTransientMarkovianAnalysis(step, Gamma, K, progress)) { + return false; + } + //printStateSetStatus(globalStateSet, "middle of transient analysis"); + failureProb = 0; + successProb = 0; + // for (String state : stateGraph.keySet()) { + // for (State m : stateGraph.get(state)) { + //for (State m : stateGraph) { + for (PrjState m : globalStateSet.keySet()) { + ExprTree failureExpr = new ExprTree(varNameList); + failureExpr.token = failureExpr.intexpr_gettok("~(" + condition[0] + ")&~(" + condition[1] + + ")"); + failureExpr.intexpr_L("~(" + condition[0] + ")&~(" + condition[1] + ")"); + ExprTree successExpr = new ExprTree(varNameList); + if (globallyTrue) { + successExpr.token = successExpr.intexpr_gettok("~(" + condition[1] + ")"); + successExpr.intexpr_L("~(" + condition[1] + ")"); + } + else { + successExpr.token = successExpr.intexpr_gettok(condition[1]); + successExpr.intexpr_L(condition[1]); + } + if (failureExpr.evaluateExpr(((ProbGlobalState) m).getVariables()) == 1.0) { + failureProb += ((ProbGlobalState) m).getCurrentProb(); + } + else if (successExpr.evaluateExpr(((ProbGlobalState) m).getVariables()) == 1.0) { + successProb += ((ProbGlobalState) m).getCurrentProb(); + } + // } + } + if (globallyTrue) { + successProb = 1 - successProb; + } + if (lowerbound + i + step == nextPrint) { + probData.getData().get(0).add(nextPrint); + probData.getData().get(1).add(failureProb * 100); + probData.getData().get(2).add(successProb * 100); + nextPrint += printInterval; + } + } + HashMap output = new HashMap(); + failureProb = 0; + successProb = 0; + double timelimitProb = 0; + for (PrjState m : globalStateSet.keySet()) { + ExprTree failureExpr = new ExprTree(varNameList); + failureExpr.token = failureExpr.intexpr_gettok("~(" + condition[0] + ")&~(" + condition[1] + ")"); + failureExpr.intexpr_L("~(" + condition[0] + ")&~(" + condition[1] + ")"); + ExprTree successExpr = new ExprTree(varNameList); + if (globallyTrue) { + successExpr.token = successExpr.intexpr_gettok("~(" + condition[1] + ")"); + successExpr.intexpr_L("~(" + condition[1] + ")"); + } + else { + successExpr.token = successExpr.intexpr_gettok(condition[1]); + successExpr.intexpr_L(condition[1]); + } + if (failureExpr.evaluateExpr(((ProbGlobalState) m).getVariables()) == 1.0) { + failureProb += ((ProbGlobalState) m).getCurrentProb(); + } + else if (successExpr.evaluateExpr(((ProbGlobalState) m).getVariables()) == 1.0) { + successProb += ((ProbGlobalState) m).getCurrentProb(); + } + else { + if (!globallyTrue) { + timelimitProb += ((ProbGlobalState) m).getCurrentProb(); + } + } + // } + } + if (globallyTrue) { + successProb = 1 - successProb; + timelimitProb = 1 - (failureProb + successProb); + } + output.put("Failure", failureProb); + output.put("Success", successProb); + output.put("Timelimit", timelimitProb); + /* + String result1 = "#total"; + String result2 = "1.0"; + for (String s : output.keySet()) { + result1 += " " + s; + result2 += " " + output.get(s); + } + */ + // --- Temp: Print results ----- + System.out.println("Failure = " + failureProb); + System.out.println("Success = " + successProb); + System.out.println("Timelimit = " + timelimitProb); + // ----------------------------- + return true; + } + return false; + } + progress.setMaximum((int) timeLimit); + ProbGlobalState initial = (ProbGlobalState) globalStateSet.getInitialState(); + if (initial != null) { + initial.setCurrentProb(1.0); + initial.setPiProb(1.0); + boolean stop = false; + // Compute Gamma + double Gamma = 0; + for (PrjState m : globalStateSet.keySet()) + Gamma = Math.max(((ProbGlobalState) m).getTranRateSum(), Gamma); + // Compute K + int K = 0; + double xi = 1; + double delta = 1; + double eta = (1 - error) / (Math.pow(Math.E, ((0 - Gamma) * timeStep))); + while (delta < eta) { + K = K + 1; + xi = xi * ((Gamma * timeStep) / K); + delta = delta + xi; + } + for (double i = 0; i < timeLimit; i += timeStep) { + double step = Math.min(timeStep, timeLimit - i); + if (step == timeLimit - i) { + // Compute K + K = 0; + xi = 1; + delta = 1; + eta = (1 - error) / (Math.pow(Math.E, ((0 - Gamma) * step))); + while (delta < eta) { + K = K + 1; + xi = xi * ((Gamma * step) / K); + delta = delta + xi; + } + } + stop = !performTransientMarkovianAnalysis(step, Gamma, K, progress); + progress.setValue((int) i); + if (stop) { + return false; + } + } + return !stop; + } + return false; + } + + private synchronized boolean performTransientMarkovianAnalysis(double timeLimit, double Gamma, int K, + JProgressBar progress) { + if (timeLimit == 0.0) { + return true; + } + int progressValue = 0; + if (progress != null) { + progressValue = progress.getValue(); + } + // Approximate pi(t) + threadCount = 4; + waitingThreads = threadCount; + phase1 = true; + phase2 = false; + Object[] globalStArray = globalStateSet.keySet().toArray(); + for (int i = 0; i < globalStArray.length; i++) { + ProbGlobalState m = (ProbGlobalState) globalStArray[i]; + if (m.isAbsorbing()) { + m.setNextProb(m.getCurrentProb()); + } + else { + m.setNextProb(m.getCurrentProb() * (1 - (m.getTranRateSum() / Gamma))); + } + } + ArrayList threads = new ArrayList(); + for (int i = 0; i < threadCount; i++) { + TransientMarkovMatrixMultiplyThread thread = new TransientMarkovMatrixMultiplyThread(this); + thread.start((i * globalStateSet.keySet().size()) / threadCount, ((i + 1) * globalStateSet.keySet().size()) / threadCount, Gamma, + timeLimit, K); + threads.add(thread); + } + for (int k = 1; k <= K && !stop; k++) { + while (waitingThreads != 0) { + try { + notifyAll(); + wait(); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (stop) { + for (TransientMarkovMatrixMultiplyThread thread : threads) { + try { + thread.join(); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + } + return false; + } + phase1 = false; + phase2 = true; + while (waitingThreads != threadCount) { + try { + notifyAll(); + wait(); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (stop) { + for (TransientMarkovMatrixMultiplyThread thread : threads) { + try { + thread.join(); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + } + return false; + } + phase1 = true; + phase2 = false; + if (progress != null) { + progress.setValue(progressValue + ((int) ((timeLimit * k) / K))); + } + /* + * for (State m : stateGraph) { //for (String state : + * stateGraph.keySet()) { // for (State m : stateGraph.get(state)) { + * double nextProb = m.getCurrentProb() (1 - + * (m.getTransitionSum(0.0, null) / Gamma)); for + * (StateTransitionPair prev : m.getPrevStatesWithTrans()) { // if + * (lhpn.getTransitionRateTree(prev.getTransition()) // != null) { + * // prob = // + * lhpn.getTransitionRateTree(prev.getTransition()).evaluateExpr + * (prev.getState().getVariables()); // } nextProb += + * (prev.getState().getCurrentProb() * (prev.getTransition() / + * Gamma)); } m.setNextProb(nextProb * ((Gamma * timeLimit) / k)); + * m.setPiProb(m.getPiProb() + m.getNextProb()); //} } if (stop) { + * return false; } for (State m : stateGraph) { //for (String state + * : stateGraph.keySet()) { //for (State m : stateGraph.get(state)) + * { m.setCurrentProbToNext(); //} } progress.setValue(progressValue + * + ((int) ((timeLimit * k) / K))); + */ + } + try { + while (waitingThreads != 0) { + try { + notifyAll(); + wait(10); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + } + for (TransientMarkovMatrixMultiplyThread thread : threads) { + thread.join(); + } + } + catch (InterruptedException e) { + e.printStackTrace(); + } + if (!stop) { + for (PrjState m : globalStateSet.keySet()) { + ((ProbGlobalState) m).setPiProb(((ProbGlobalState) m).getPiProb() * (Math.pow(Math.E, ((0 - Gamma) * timeLimit)))); + ((ProbGlobalState) m).setCurrentProbToPi(); + // } + } + } + if (stop) { + return false; + } + return true; + } + + public synchronized void transientMarkovMatrixMultiplication(int startIndex, int endIndex, double Gamma, + double timeLimit, int K) { + Object[] globalStateArray = globalStateSet.keySet().toArray(); + for (int k = 1; k <= K && !stop; k++) { + for (int i = startIndex; i < endIndex; i++) { + ProbGlobalState curState = (ProbGlobalState) globalStateArray[i]; + if (!curState.isAbsorbing()) { +// for (Transition outTran : curState.getOutgoingTranSetForProbGlobalState()) { +// ProbGlobalState nextState = (ProbGlobalState) curState.getNextGlobalState(outTran); + for (Transition outTran : curState.getNextGlobalStateMap().keySet()) { + PrjState nextState = curState.getNextGlobalStateMap().get(outTran); + try { + ((ProbGlobalState) nextState).lock.acquire(); + ((ProbGlobalState) nextState).setNextProb( + ((ProbGlobalState) nextState).getNextProb() + + (curState.getCurrentProb() * (curState.getOutgoingTranRate(outTran) / Gamma))); + } catch (InterruptedException e) { + e.printStackTrace(); + } + ((ProbGlobalState) nextState).lock.release(); + } + } + if (stop) { + waitingThreads--; + notifyAll(); + return; + } + } + waitingThreads--; + if (waitingThreads == 0) { + notifyAll(); + } + try { + while (!phase2 && !stop) { + wait(); + } + } + catch (InterruptedException e) { + e.printStackTrace(); + } + for (int i = startIndex; i < endIndex; i++) { + ProbGlobalState m = (ProbGlobalState) globalStateArray[i]; + m.setNextProb(m.getNextProb() * ((Gamma * timeLimit) / k)); + m.setPiProb(m.getPiProb() + m.getNextProb()); + m.setCurrentProbToNext(); + if (m.isAbsorbing()) { + m.setNextProb(m.getCurrentProb()); + } + else { + m.setNextProb(m.getCurrentProb() * (1 - (m.getTranRateSum() / Gamma))); + } + if (stop) { + waitingThreads++; + notifyAll(); + return; + } + } + waitingThreads++; + if (waitingThreads == threadCount) { + notifyAll(); + } + try { + while (!phase1 && !stop) { + wait(); + } + } + catch (InterruptedException e) { + e.printStackTrace(); + } + if (stop) { + return; + } + } + waitingThreads--; + } + + public void pruneStateGraph(String condition) { + for (PrjState m : globalStateSet.keySet()) { + ExprTree expr = new ExprTree(varNameList); + expr.token = expr.intexpr_gettok(condition); + expr.intexpr_L(condition); + if (expr.evaluateExpr(((ProbGlobalState) m).getVariables()) == 1.0) { + ((ProbGlobalState) m).setAbsorbing(true); + } + } + } +// +// /** +// * This method do or undo pruning for a given transition based on the pruneFlag. +// * +// * @param pruneFlag +// * @param curProbGlobalSt +// * @param outTran +// */ +// public void pruneTransition(boolean pruneFlag, PrjState curProbGlobalSt, Transition outTran) { +// // The local state index (in a global state) is the same as its corresponding lpn index. +// int localStateIndex = outTran.getLpn().getLpnIndex(); +// State localState = curProbGlobalSt.toStateArray()[localStateIndex]; +// ProbLocalStateGraph localSg = ((ProbLocalStateGraph) localState.getStateGraph()); +// double tranRate = localSg.getTranRate(localState, outTran); +// if (pruneFlag && (tranRate > 0.0)) { // Set tranRate to negative since outTran is pruned. +// localSg.setTranRate(localState, outTran, (-1* tranRate)); +// } +// else if (!pruneFlag && (tranRate < 0.0)) { // Restore tranRate to positive. +// localSg.setTranRate(localState, outTran, (-1* tranRate)); +// } +// } + +// public void enableAllTransitions() { +// // Need to consider the case where next global state map exists. +// for (State localInitSt : globalStateSet.getInitialState().toStateArray()) { +// ProbLocalStateGraph localSg = (ProbLocalStateGraph) localInitSt.getStateGraph(); +// HashMap> nextTranRateMap = localSg.getNextTranRateMap(); +// for (State localSt : nextTranRateMap.keySet()) { +// for (Transition outTran : localSt.getOutgoingTranSet()) { +// if (localSg.getTranRate(localSt, outTran) < 0.0) { +// double tranRate = localSg.getTranRate(localSt, outTran); +// // Set tranRate to positive. We use negative rate to indicate a pruned transition. +// localSg.setTranRate(localSt, outTran, Math.abs(tranRate)); +// } +// } +// } +// } +// } + + public void setAllGlobalStatesAsNonAbsorbing() { + for (PrjState m : globalStateSet.keySet()) { + ((ProbGlobalState) m).setAbsorbing(false); + } + } + + @Override + public void run() { + + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/PerfromTransientMarkovAnalysisThread.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/PerfromTransientMarkovAnalysisThread.java new file mode 100644 index 000000000..eaf5c67ba --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/PerfromTransientMarkovAnalysisThread.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.markovianAnalysis; +import javax.swing.JProgressBar; + +import edu.utah.ece.async.ibiosim.dataModels.util.exceptions.BioSimException; + + +/** + * This class is used to construct threads for transient or nested Markovian analysis. + * @author Zhen Zhang (adapted from Curtis Madsen's PerformTransientMarkovAnalysisThread class) + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class PerfromTransientMarkovAnalysisThread extends Thread { + + //private ProbGlobalStateSet globalStateSet; + private MarkovianAnalysis markovianAnalysis; + + private JProgressBar progress; + + private double timeLimit, timeStep, printInterval, error; + + private String[] condition; + + private boolean globallyTrue; + + public PerfromTransientMarkovAnalysisThread(MarkovianAnalysis markovianAnalysis, JProgressBar progress) { + super(markovianAnalysis); + this.markovianAnalysis = markovianAnalysis; + this.progress = progress; + } + + public void start(double timeLimit, double timeStep, double printInterval, double error, String[] condition, boolean globallyTrue) { + this.timeLimit = timeLimit; + this.timeStep = timeStep; + this.printInterval = printInterval; + this.error = error; + this.condition = condition; + this.globallyTrue = globallyTrue; + progress.setIndeterminate(false); + progress.setString(null); + super.start(); + } + + @Override + public void run() { + try { + markovianAnalysis.performTransientMarkovianAnalysis(timeLimit, timeStep, printInterval, error, condition, progress, globallyTrue); + } catch (BioSimException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbGlobalState.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbGlobalState.java new file mode 100644 index 000000000..1520624e2 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbGlobalState.java @@ -0,0 +1,288 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.markovianAnalysis; + +import java.util.HashMap; +import java.util.concurrent.Semaphore; + +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.project.PrjState; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ProbGlobalState extends PrjState { + + private int color; + + private double currentProb; + + private double nextProb; + + private double piProb; + + /** + * This maps stores transition rate for each outgoing transition. + */ + private HashMap nextGlobalTranRateMap; + + /** + * Sum of all outgoing transition rates from this state. + */ + private double tranRateSum; + + /** + * This map stores for each state the probability value computed when checking + * a nested property. + * key: "Pr" + nestedPropString.hashCode() or "St" + nestedPropString.hashCode() + * value: success probability + */ + private HashMap nestedProbValues; + + public Semaphore lock; + + private boolean isAbsorbing; + + + + public ProbGlobalState(State[] other) { + super(other); + tranRateSum = 0.0; + nextGlobalStateMap = new HashMap(); + nextGlobalTranRateMap = new HashMap(); + lock = new Semaphore(1); + isAbsorbing = false; + } + + public boolean isAbsorbing() { + return isAbsorbing; + } + + public void setAbsorbing(boolean isAbsorbing) { + this.isAbsorbing = isAbsorbing; + } + + public HashMap getNestedProbValues() { + return nestedProbValues; + } + + public void addNestedProb(String id, String value) { + if (nestedProbValues == null) + nestedProbValues = new HashMap(); + nestedProbValues.put(id, value); + } + + public int getColor() { + return color; + } + + public void setColor(int color) { + this.color = color; + } + + public double getCurrentProb() { + return currentProb; + } + + public void setCurrentProb(double currentProb) { + this.currentProb = currentProb; + } + + public double getNextProb() { + return nextProb; + } + + public void setNextProb(double nextProb) { + this.nextProb = nextProb; + } + + public void setCurrentProbToNext() { + currentProb = nextProb; + } + +// public double getOutgoingTranRate(Transition tran) { +// int curLocalStIndex = tran.getLpn().getLpnIndex(); +// State curLocalState = this.toStateArray()[curLocalStIndex]; +// double tranRate = ((ProbLocalStateGraph) curLocalState.getStateGraph()).getTranRate(curLocalState, tran); +// return tranRate; +// } + + public double getOutgoingTranRate(Transition tran) { + return nextGlobalTranRateMap.get(tran); + } + + public double getTranProb(Transition tran) { + double tranProb = 0.0; + if (tranRateSum != 0) + tranProb = getOutgoingTranRate(tran)/tranRateSum; + else + tranProb = 0.0; + return tranProb; + } + + public double getPiProb() { + return piProb; + } + + public void setPiProb(double piProb) { + this.piProb = piProb; + } + +// /** +// * If nextProbGlobalStateMap exists, this method returns the value field of it. +// * If not, this method uses local state-transition information to search for the next global states of +// * this current global state, and returns a set of such next global states. The search +// * is performed based on the local states that this current global state is composed of. For example, assume a current +// * global state S0 is composed of n (n>=1) local states: s_00,s_10,s_20...,s_n0. For each outgoing transition, t_k, of +// * s_00, it finds in each of the local state, namely s_00, s_10, s_20, ..., s_n0, their next local states. It then +// * pieces them together to form a next global state. Next, it grabs the equivalent one from the global state set. The obtained is a +// * next global state reached from S0 by taking t_k. The whole process repeats for s_10, s_20, ..., s_n0. All obtained +// * next global states are added to a set and returned by this method. +// * @param globalStateSet +// * @return +// */ +// public HashSet getNextProbGlobalStateSet(ProbGlobalStateSet globalStateSet) { +// HashSet nextProbGlobalStateSet = new HashSet(); +// for (Transition outTran : nextGlobalStateMap.keySet()) +// nextProbGlobalStateSet.add((ProbGlobalState) getNextGlobalState(outTran)); +// return nextProbGlobalStateSet; + //if (Options.getBuildGlobalStateGraph()) { +// for (Transition outTran : nextGlobalStateMap.keySet()) +// nextProbGlobalStateSet.add((ProbGlobalState) getNextGlobalState(outTran)); +// return nextProbGlobalStateSet; + //} +// else { +// for (State localSt : this.toStateArray()) +// for (Transition outTran : localSt.getOutgoingTranSet()) +// nextProbGlobalStateSet.add((ProbGlobalState) getNextGlobalState(outTran, globalStateSet)); +// return nextProbGlobalStateSet; +// } +// } + +// /** +// * If nextProbGlobalStateMap exists, this method returns the value for the given outTran, else it calls +// * getNextPrjState(Transition, HashMap) in PrjState.java. +// * @param outTran +// * @param globalStateSet +// * @return +// */ +// public PrjState getNextGlobalState(Transition outTran, ProbGlobalStateSet globalStateSet) { +// if (Options.getBuildGlobalStateGraph()) +// return nextGlobalStateMap.get(outTran); +// else { +// State[] tmpNextStateArray = new State[this.toStateArray().length]; +// for (State curLocalSt : this.toStateArray()) { +// State nextLocalSt = curLocalSt.getNextLocalState(outTran); +// if (nextLocalSt != null) { // outTran leads curLocalSt to a next state. +// tmpNextStateArray[curLocalSt.getLpn().getLpnIndex()] = nextLocalSt; +// } +// else { // No nextLocalSt was found. Transition outTran did not change this local state. +// tmpNextStateArray[curLocalSt.getLpn().getLpnIndex()] = curLocalSt; +// } +// } +// PrjState tmpPrjSt = new ProbGlobalState(tmpNextStateArray); +// if (((ProbGlobalStateSet)globalStateSet).get(tmpPrjSt) == null) { +// String curGlobalStLabel = ""; +// String tmpPrjStLabel = ""; +// for (State s : this.toStateArray()) { +// curGlobalStLabel += s.getFullLabel() + "_"; +// } +// for (State s : tmpPrjSt.toStateArray()) { +// tmpPrjStLabel += s.getFullLabel() + "_"; +// } +// String message = "Next global state was not found for current global state: " +// + curGlobalStLabel.substring(0, curGlobalStLabel.length()-1) + "," +// + "\ngiven transition " + outTran.getFullLabel() +// + ".\ntmpPrjSt = " + tmpPrjStLabel.substring(0, tmpPrjStLabel.length()-1) + ".\n" +// + "Next local state map:\n"; +// for (State s : this.toStateArray()) { +// if (s.getNextLocalState(outTran) == null) +// message += s.getFullLabel() + " -> null\n"; +// else +// message += s.getFullLabel() + " ->" + s.getNextLocalState(outTran).getFullLabel() + "\n"; +// } +// NullPointerException npe = new NullPointerException(message); +// throw npe; +// } +// return ((ProbGlobalStateSet) globalStateSet).get(tmpPrjSt); +// } +// } + +// /** +// * If nextProbGlobalStateMap exists, this method returns the keySet of it. Otherwise, it calls +// * getOutgoingTrans() in PrjState.java. +// * @return +// */ +// public Set getOutgoingTranSetForProbGlobalState() { +// return nextGlobalStateMap.keySet(); +//// if (Options.getBuildGlobalStateGraph()) +//// return nextGlobalStateMap.keySet(); +//// else { +//// Set outgoingTrans = new HashSet(); +//// for (State curLocalSt : this.toStateArray()) +//// outgoingTrans.addAll(curLocalSt.getOutgoingTranSet()); +//// return outgoingTrans; +//// } +// } + + public void computeTranRateSum() { + for (Transition tran : nextGlobalStateMap.keySet()) { + tranRateSum += getOutgoingTranRate(tran); + } + } + + public double getTranRateSum() { + return tranRateSum; + } + +// public boolean isExplored() { +// return isExplored; +// } +// +// public void markAsExplored() { +// isExplored = true; +// } +// +// public void resetExplored() { +// isExplored = false; +// } + + public void setCurrentProbToPi() { + currentProb = piProb; + } + + public void setTranRateSum(double tranRateSum) { + this.tranRateSum = tranRateSum; + } + + public HashMap getVariables() { + HashMap varMap = new HashMap(); + for (State localSt : this.toStateArray()) { + varMap.putAll(localSt.getLpn().getAllVarsWithValuesAsString(localSt.getVariableVector())); + } + if (nestedProbValues != null) + varMap.putAll(nestedProbValues); + return varMap; + } + + public void addNextGlobalTranRate(Transition t, double tranRate) { + this.nextGlobalTranRateMap.put(t, tranRate); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbGlobalStateSet.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbGlobalStateSet.java new file mode 100644 index 000000000..beb404d23 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbGlobalStateSet.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.markovianAnalysis; + +import java.util.HashMap; +import java.util.Iterator; + +import edu.utah.ece.async.lema.verification.platu.logicAnalysis.StateSetInterface; +import edu.utah.ece.async.lema.verification.platu.project.PrjState; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ProbGlobalStateSet extends HashMap implements StateSetInterface, Runnable {//extends HashSet{ + + private static final long serialVersionUID = 1L; + + private PrjState initState; + + public ProbGlobalStateSet() { + super(); + } + + /* + * Get the initial state. + */ + public PrjState getInitialState() { + return initState; + } + + /* + * Set the initial state. + * @param initState + * The initial state. + */ + public void setInitState(PrjState initPrjState) { + this.initState = initPrjState; + } + + @Override + public boolean contains(PrjState s) { + return this.keySet().contains(s); + } + + @Override + public boolean add(PrjState state) { + super.put(state, state); + return false; + } + + @Override + public Iterator iterator() { + return super.keySet().iterator(); + } + + @Override + public void run() { + } + + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbLocalState.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbLocalState.java new file mode 100644 index 000000000..c64390059 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbLocalState.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.markovianAnalysis; + +import java.util.HashMap; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.platuLpn.DualHashMap; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ProbLocalState extends State{ + + public ProbLocalState(LPN lpn, int[] marking, int[] vector, + boolean[] tranVector) { + super(lpn, marking, vector, tranVector); + } + + /* (non-Javadoc) + * @see verification.platu.stategraph.State#update(verification.platu.stategraph.StateGraph, java.util.HashMap, verification.platu.lpn.DualHashMap) + * Return a new state if the newVector leads to a new state from this state; otherwise return null. Also, adjust the tranRateVector. + */ + @Override + public State update(StateGraph thisSg, HashMap newVector, DualHashMap VarIndexMap) { + int[] newVariableVector = new int[this.vector.length]; + boolean nextStateExists = false; + for(int index = 0; index < vector.length; index++) { + String var = VarIndexMap.getKey(index); + int this_val = this.vector[index]; + Integer newVal = newVector.get(var); + if(newVal != null) { + if(this_val != newVal) { + nextStateExists = true; + newVariableVector[index] = newVal; + } + else + newVariableVector[index] = this.vector[index]; + } + else + newVariableVector[index] = this.vector[index]; + } + if(nextStateExists) { + HashMap tranRateMapForNextState = new HashMap(); + boolean[] newTranVector= ((ProbLocalStateGraph)thisSg).updateTranVector(this, this.marking, newVariableVector, null, tranRateMapForNextState); + State nextState = thisSg.addState(new ProbLocalState(this.lpn, this.marking, newVariableVector, newTranVector)); + ((ProbLocalStateGraph) thisSg).addTranRate(nextState, tranRateMapForNextState); + if (Options.getDebugMode()) { + String location = "ProbLocalState.java, update()"; + ((ProbLocalStateGraph) thisSg).printNextProbLocalTranRateMapForGivenState(nextState, location); + } + return nextState; + } + return null; + } + +} + + diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbLocalStateGraph.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbLocalStateGraph.java new file mode 100644 index 000000000..b1aaa92b5 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/ProbLocalStateGraph.java @@ -0,0 +1,505 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.markovianAnalysis; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.util.HashMap; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Place; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ProbLocalStateGraph extends StateGraph { + + /** + * This map stores each state's outgoing transition rates. + */ + private HashMap> nextTranRateMap; + + public ProbLocalStateGraph(LPN lpn) { + super(lpn); + nextTranRateMap = new HashMap>(); + } + + @Override + public void drawLocalStateGraph() { + try { + String graphFileName = null; + if (Options.getPOR() == null) + graphFileName = Options.getPrjSgPath() + getLpn().getLabel() + "_local_sg.dot"; + else + graphFileName = Options.getPrjSgPath() + getLpn().getLabel() + "POR_"+ Options.getCycleClosingMthd() + "_local_sg.dot"; + int size = this.lpn.getVarIndexMap().size(); + String varNames = ""; + for(int i = 0; i < size; i++) { + varNames = varNames + ", " + this.lpn.getVarIndexMap().getKey(i); + } + varNames = varNames.replaceFirst(", ", ""); + BufferedWriter out = new BufferedWriter(new FileWriter(graphFileName)); + out.write("digraph G {\n"); + out.write("Inits [shape=plaintext, label=\"<" + varNames + ">\"]\n"); + for (State curState : nextStateMap.keySet()) { + String markings = intArrayToString("markings", curState); + String vars = intArrayToString("vars", curState); + String enabledTrans = boolArrayToString("enabledTrans", curState); + String curStateName = "S" + curState.getIndex(); + out.write(curStateName + "[shape=\"ellipse\",label=\"" + curStateName + "\\n<"+vars+">" + "\\n<"+enabledTrans+">" + "\\n<"+markings+">" + "\"]\n"); + } + for (State curState : nextStateMap.keySet()) { + HashMap stateTransitionPair = nextStateMap.get(curState); + for (Transition curTran : stateTransitionPair.keySet()) { + String curStateName = "S" + curState.getIndex(); + String nextStateName = "S" + stateTransitionPair.get(curTran).getIndex(); + String curTranName = curTran.getLabel(); + if (curTran.isFail() && !curTran.isPersistent()) + out.write(curStateName + " -> " + nextStateName + " [label=\"" + curTranName + "\", fontcolor=red]\n"); + else if (!curTran.isFail() && curTran.isPersistent()) + out.write(curStateName + " -> " + nextStateName + " [label=\"" + curTranName + "\", fontcolor=blue]\n"); + else if (curTran.isFail() && curTran.isPersistent()) + out.write(curStateName + " -> " + nextStateName + " [label=\"" + curTranName + "\", fontcolor=purple]\n"); + else + out.write(curStateName + " -> " + nextStateName + " [label=\"" + curTranName + "\"]\n"); + } + } + out.write("}"); + out.close(); + } + catch (Exception e) { + e.printStackTrace(); + System.err.println("Error producing local ProbabilisticState graph as dot file."); + } + } + + /** + * This method updates the tranVector for the next state and creates the corresponding tranRateVector. If a transition is not enabled, + * its corresponding rate is marked as 0. Note that this method ONLY applies to transitions with non-empty delay expressions. + * @param enabledTransAfterFiring + * @param newMarking + * @param newVariableVector + * @param firedTran + * @param tranRateMapForNewState + */ + public boolean[] updateTranVector(State state, int[] newMarking, int[] newVariableVector, Transition firedTran, HashMap tranRateMapForNewState) { + boolean[] tranVectorAfterFiring = state.getTranVector().clone(); + // Disable the fired transition and all of its conflicting transitions. + if (firedTran != null) { + tranVectorAfterFiring[firedTran.getIndex()] = false; + for (Integer curConflictingTranIndex : firedTran.getConflictSetTransIndices()) { + tranVectorAfterFiring[curConflictingTranIndex] = false; + } + } + // find newly enabled transition(s) based on the updated markings and variables + tran_iteration : for (Transition tran : this.lpn.getAllTransitions()) { + String tranName = tran.getLabel(); + int tranIndex = tran.getIndex(); + if (Options.getDebugMode()) { + // System.out.println("Checking " + tranName); + } + if (this.lpn.getEnablingTree(tranName) != null + && this.lpn.getEnablingTree(tranName).evaluateExpr(this.lpn.getAllVarsWithValuesAsString(newVariableVector)) == 0.0) { + if (Options.getDebugMode()) { + System.out.println(tran.getFullLabel() + " " + "Enabling condition is false."); + } + if (tranVectorAfterFiring[tranIndex] && !tran.isPersistent()) { + tranVectorAfterFiring[tranIndex] = false; + } + continue; + } + if (this.lpn.getPreset(tranName) != null && this.lpn.getPreset(tranName).length != 0) { + for (int place : this.lpn.getPresetIndex(tranName)) { + if (newMarking[place]==0) { + if (Options.getDebugMode()) { + System.out.println(tran.getFullLabel() + " " + "Missing a preset token."); + } + if (tranVectorAfterFiring[tranIndex]) { + tranVectorAfterFiring[tranIndex] = false; + } + continue tran_iteration; + } + } + } + if (this.lpn.getTransitionRateTree(tranName) != null) { + double tranRate = this.lpn.getTransitionRateTree(tranName).evaluateExpr(this.lpn.getAllVarsWithValuesAsString(newVariableVector)); + if (tranRate == 0.0) { + if (Options.getDebugMode()) { + System.out.println(tran.getFullLabel() + " Rate is zero."); + } + if (tranVectorAfterFiring[tranIndex]) { + tranVectorAfterFiring[tranIndex] = false; + } + continue; + } + // if a transition passes all tests above, it needs to be marked as enabled. + tranVectorAfterFiring[tranIndex] = true; + tranRateMapForNewState.put(tran, tranRate); + if (Options.getDebugMode()) { + System.out.println(tran.getFullLabel() + " is Enabled."); + if (Options.getMarkovianModelFlag()) { + System.out.println("Added a new entry below to the inner transition rate map."); + System.out.println("tran = " + tran.getFullLabel() + ", rate = " + tranRate); + System.out.println("-------------------------"); + } + } + } + else { + System.out.println("Transition " + tran.getFullLabel() + "has empty delay expression."); + new NullPointerException().printStackTrace(); + } + } + return tranVectorAfterFiring; + } + +// /** +// * Add firedTran, its rate, and nextSt to the next state tuple map. +// * @param curSt +// * @param firedTran +// * @param firedTranRate +// * @param nextSt +// */ +// public void addStateTran(State curSt, Transition firedTran, double firedTranRate, State nextSt) { +// HashMap nextStTupleMap = this.nextProbLocalStateTupleMap.get(curSt); +// if(nextStTupleMap == null) { +// nextStTupleMap = new HashMap(); +// nextStTupleMap.put(firedTran, new ProbLocalStateTuple(nextSt, firedTranRate)); +// this.nextProbLocalStateTupleMap.put(curSt, nextStTupleMap); +// } +// else +// nextStTupleMap.put(firedTran, new ProbLocalStateTuple(nextSt, firedTranRate)); +// if (Options.getDebugMode()) { +// System.out.println("**** Added <" + firedTran.getFullLabel() + ", S" + nextSt.getIndex() + "(" + curSt.getLpn().getLabel() +// +")> to the next state tuple map of state S" + curSt.getIndex() + "(" + curSt.getLpn().getLabel() +")"); +// } +// } + +// public State getNextState(State curSt, Transition firedTran) { +// HashMap nextMap = this.nextProbLocalStateTupleMap.get(curSt); +// if(nextMap == null || nextMap.get(firedTran) == null || nextMap.get(firedTran).getNextProbLocalState() == null) +// return null; +// return nextMap.get(firedTran).getNextProbLocalState(); +// } + +// public ProbLocalStateTuple getNextStateTuple(State curState, +// Transition firedTran) { +// HashMap nextMap = this.nextProbLocalStateTupleMap.get(curState); +// if(nextMap == null || nextMap.get(firedTran) == null) +// return null; +// return nextMap.get(firedTran); +// } + +// public HashMap> getNextProbLocalStateTupleMap() { +// return this.nextProbLocalStateTupleMap; +// } + + @Override + public State genInitialState() { + // create initial vector + int size = this.lpn.getVarIndexMap().size(); + int[] initVariableVector = new int[size]; + for(int i = 0; i < size; i++) { + String var = this.lpn.getVarIndexMap().getKey(i); + int val = this.lpn.getInitVariableVector(var); + initVariableVector[i] = val; + } + HashMap initTranRateMap = new HashMap(); + boolean[] initTranVector = genInitTranVector(initVariableVector, initTranRateMap); + this.init = new ProbLocalState(this.lpn, this.lpn.getInitialMarkingsArray(), initVariableVector, initTranVector); + this.addTranRate(this.init, initTranRateMap); + if (Options.getDebugMode()) + printNextProbLocalTranRateMapForGivenState(this.init, "ProbLocalStateGraph.java -> genInitialState()"); + return this.init; + } + + /* (non-Javadoc) + * @see verification.platu.stategraph.StateGraph#fire(verification.platu.stategraph.StateGraph, verification.platu.stategraph.State, lpn.parser.Transition) + * Fire a transition, generate the local next state (if it is not created yet) from the current local state. Also, update the enabled transition vector + * and its corresponding tranRate vector. + */ + @Override + public State fire(final StateGraph thisSg, final State curState, Transition firedTran){ + State nextState = thisSg.getNextState(curState, firedTran); + if(nextState != null) { + if (Options.getDebugMode()) { + System.out.println("@ ProbLocalStateGraph.java -> fire(StateGraph, State, Transition), nextState is not null. nextState = S" + + nextState.getIndex() + "("+ nextState.getLpn().getLabel() + ")"); + } + return nextState; + } + // If no cached next state exists, do regular firing. + // Marking update + int[] curOldMarking = curState.getMarking(); + int[] curNewMarking = null; + if(firedTran.getPreset().length==0 && firedTran.getPostset().length==0) + curNewMarking = curOldMarking; + else { + curNewMarking = new int[curOldMarking.length]; + curNewMarking = curOldMarking.clone(); + for (int prep : this.lpn.getPresetIndex(firedTran.getLabel())) { + curNewMarking[prep]=0; + } + for (int postp : this.lpn.getPostsetIndex(firedTran.getLabel())) { + curNewMarking[postp]=1; + } + } + + // Variable vector update + int[] newVariableVector = curState.getVariableVector().clone(); + int[] curVector = curState.getVariableVector(); + HashMap currentValuesAsString = this.lpn.getAllVarsWithValuesAsString(curVector); + for (String key : currentValuesAsString.keySet()) { + if (this.lpn.getBoolAssignTree(firedTran.getLabel(), key) != null) { + int newValue = (int)this.lpn.getBoolAssignTree(firedTran.getLabel(), key).evaluateExpr(currentValuesAsString); + newVariableVector[this.lpn.getVarIndexMap().get(key)] = newValue; + } + if (this.lpn.getIntAssignTree(firedTran.getLabel(), key) != null) { + int newValue = (int)this.lpn.getIntAssignTree(firedTran.getLabel(), key).evaluateExpr(currentValuesAsString); + newVariableVector[this.lpn.getVarIndexMap().get(key)] = newValue; + } + } + // Enabled transition vector update + HashMap tranRateMapForNewState = new HashMap(); + boolean[] newTranVector = updateTranVector(curState, curNewMarking, newVariableVector, firedTran, tranRateMapForNewState); + State newState = thisSg.addState(new ProbLocalState(this.lpn, curNewMarking, newVariableVector, newTranVector)); + // TODO: (future) assertions in our LPN? + /* + int[] newVector = newState.getVector(); + for(Expression e : assertions){ + if(e.evaluate(newVector) == 0){ + System.err.println("Assertion " + e.toString() + " failed in LPN transition " + this.lpn.getLabel() + ":" + this.label); + System.exit(1); + } + } + */ + thisSg.addStateTran(curState, firedTran, newState); + ((ProbLocalStateGraph) thisSg).addTranRate(newState, tranRateMapForNewState); + if (Options.getDebugMode()) { + String location = "ProbLocalStateGraph.java, overriden fire(ProbLocalStateGraph, State, Transition)"; + thisSg.printNextStateForGivenState(curState, location); + ((ProbLocalStateGraph) thisSg).printNextProbLocalTranRateMapForGivenState(newState, location); + } + return newState; + } + + + /* (non-Javadoc) + * @see verification.platu.stategraph.StateGraph#genInitTranVector(int[]) + * Find enabled transitions in the initial state, and construct the tranVector in this state. + */ + public boolean[] genInitTranVector(int[] initVariableVector, HashMap initTranRateMap) { + boolean[] initTranVector = new boolean[this.lpn.getAllTransitions().length]; + tran_outter_loop: for (int i=0; i< this.lpn.getAllTransitions().length; i++) { + Transition tran = this.lpn.getAllTransitions()[i]; + Place[] tranPreset = this.lpn.getTransition(tran.getLabel()).getPreset(); + String tranName = tran.getLabel(); + if (this.lpn.getPreset(tranName) != null && this.lpn.getPreset(tranName).length != 0) { + for (int j=0; j getInitTranVector -----"); +// System.out.println("Printout results of getAllVarsWithVarValuesAsString(int[]) call in LhpnFile."); +// for (String varName : this.lpn.getAllVarsWithValuesAsString(initVariableVector).keySet()) { +// String varValue = this.lpn.getAllVarsWithValuesAsString(initVariableVector).get(varName); +// System.out.println(varName + " = " + varValue); +// } +// System.out.println("-------------------------------------------------"); +// // ---------------------- + double tranRate = this.lpn.getTransitionRateTree(tranName).evaluateExpr(this.lpn.getAllVarsWithValuesAsString(initVariableVector)); + if (tranRate == 0.0) { + if (Options.getDebugMode()) { + // System.out.println("Rate is zero"); + } + initTranVector[i] = false; + continue; + } + initTranRateMap.put(tran, tranRate); + initTranVector[i] = true; + } + else { + System.out.println("Transition " + tran.getFullLabel() + "has empty delay expression."); + new NullPointerException().printStackTrace(); + System.exit(1); + } + } + return initTranVector; + } + + + /* (non-Javadoc) + * @see verification.platu.stategraph.StateGraph#fire(verification.platu.stategraph.StateGraph[], verification.platu.stategraph.State[], lpn.parser.Transition) + * This method executes firedTran first by calling fire(StateGraph, State, Transition), and then it updates the affected state graphs. + */ + @Override + public State[] fire(final StateGraph[] curSgArray, final State[] curStateArray, Transition firedTran){ + int thisLpnIndex = this.getLpn().getLpnIndex(); + State[] nextStateArray = curStateArray.clone(); + State curState = curStateArray[thisLpnIndex]; + State nextState = this.fire(curSgArray[thisLpnIndex], curState, firedTran); + // TODO: (future) assertions in our LPN? + /* + for(Expression e : assertions){ + if(e.evaluate(nextVector) == 0){ + System.err.println("Assertion " + e.toString() + " failed in LPN transition " + this.lpn.getLabel() + ":" + this.label); + System.exit(1); + } + } + */ + nextStateArray[thisLpnIndex] = nextState; + if(firedTran.isLocal()) { + return nextStateArray; + } + HashMap vvSet = new HashMap(); + vvSet = this.lpn.getAllVarsWithValuesAsInt(nextState.getVariableVector()); + // update state graphs that are affected by firedTran. + // TODO: Need to deal with immediate transitions. + for(LPN curLPN : firedTran.getDstLpnList()) { + int curIdx = curLPN.getLpnIndex(); + State newState = curSgArray[curIdx].getNextState(curStateArray[curIdx], firedTran); + if(newState != null) { + nextStateArray[curIdx] = newState; + } + else { + State newOther = ((ProbLocalState) curStateArray[curIdx]).update(curSgArray[curIdx], vvSet, curSgArray[curIdx].getLpn().getVarIndexMap()); + if (newOther == null) + nextStateArray[curIdx] = curStateArray[curIdx]; + else { + State cachedOther = curSgArray[curIdx].addState(newOther); + nextStateArray[curIdx] = cachedOther; + curSgArray[curIdx].addStateTran(curStateArray[curIdx], firedTran, cachedOther); + double firedTranRate = ((ProbLocalStateGraph) curSgArray[thisLpnIndex]).getTranRate(curState, firedTran); + ((ProbLocalStateGraph) curSgArray[curIdx]).addTranRate(curStateArray[curIdx], firedTran, firedTranRate); + if (Options.getDebugMode()) { + String location = "ProbLocalStateGraph.java, overriden fire(StateGraph[], State[], Transition)"; + curSgArray[curIdx].printNextStateForGivenState(curStateArray[curIdx], location); + ((ProbLocalStateGraph) curSgArray[curIdx]).printNextProbLocalTranRateMapForGivenState(curStateArray[curIdx], location); + } + } + } + } + return nextStateArray; + } + + /** + * Add all transitions and their corresponding rates for the nextState to the nextTranRateMap. + * @param nextState + * @param nextStateTranRateMap + */ + public void addTranRate(State nextState, HashMap nextStateTranRateMap) { + HashMap innerMap = this.nextTranRateMap.get(nextState); + if (innerMap == null) { +// innerMap = new HashMap(); +// innerMap.putAll(nextStateTranRateMap); +// this.nextTranRateMap.put(nextState, innerMap); + this.nextTranRateMap.put(nextState, nextStateTranRateMap); + } + else { + // TODO: Need to remove this step. + innerMap.putAll(nextStateTranRateMap); + } + if (Options.getDebugMode()) + printNextProbLocalTranRateMapForGivenState(nextState, "ProbLocalStateGraph.java -> (public) addTranRate(). Adding state " + nextState.getFullLabel() + " to the map."); + } + + /** + * Add a single entry to the nextTranRateMap. + * @param curState + * @param firedTran + * @param tranRate + */ + private void addTranRate(State curState, Transition firedTran, + double tranRate) { + HashMap innerMap = nextTranRateMap.get(curState); + if (innerMap != null) { + innerMap.put(firedTran, tranRate); + } + else { + innerMap = new HashMap(); + innerMap.put(firedTran, tranRate); + nextTranRateMap.put(curState, innerMap); + } +// if (Options.getDebugMode()) +// printNextProbLocalTranRateMapForGivenState(curState, "ProbLocalStateGraph.java -> (private) addTranRate(). Adding state " + curState.getFullLabel() + " to the map."); + } + + public double getTranRate(State curLocalState, Transition tran) { + if (nextTranRateMap.get(curLocalState) == null) { + System.out.println("No entry for " + curLocalState.getFullLabel() + " in nextTranRateMap"); + printNextProbLocalTranRateMapForGivenState(curLocalState, "ProbLocalStateGraph.java -> getTranRate()_0"); + NullPointerException npe = new NullPointerException("Next probabilistic local state is null."); + npe.printStackTrace(); + } + else if (nextTranRateMap.get(curLocalState).get(tran) == null) { + System.out.println("No entry for " + curLocalState.getFullLabel() + " and transition " + tran.getFullLabel() + " in nextTranRateMap"); + curLocalState.printStateInfo(); + printNextProbLocalTranRateMapForGivenState(curLocalState, "ProbLocalStateGraph.java -> getTranRate()_1"); + NullPointerException npe1 = new NullPointerException("Next transition rate is null."); + npe1.printStackTrace(); + } + return nextTranRateMap.get(curLocalState).get(tran); + } + +// public void setTranRate(State curLocalState, Transition tran, double tranRate) { +// nextTranRateMap.get(curLocalState).put(tran, tranRate); +// } + +// public HashMap> getNextTranRateMap() { +// return nextTranRateMap; +// } + + public void printNextProbLocalTranRateMapForGivenState(State givenState, String location) { + System.out.println("----------------Next Tran Rate Map @ " + location + "----------------"); + System.out.println("state = " + givenState.getFullLabel()); + HashMap nextStateMapForGivenState = nextStateMap.get(givenState); + HashMap nextTranRateMapForGivenState = nextTranRateMap.get(givenState); + if (nextStateMapForGivenState == null) { + System.out.println("No entry for " + givenState.getFullLabel() + " in nextStateMap"); + } + else { + for (Transition t: nextStateMapForGivenState.keySet()) { + State nextState = nextStateMapForGivenState.get(t); + System.out.println(t.getFullLabel() + " -> S" + nextState.getIndex() + "(" + nextState.getLpn().getLabel() + ")"); + } + } + if (nextTranRateMapForGivenState == null) { + System.out.println("No entry for " + givenState.getFullLabel() + " in nextTranRateMap"); + } + else { + for (Transition t: nextTranRateMapForGivenState.keySet()) { + Double tranRate = nextTranRateMapForGivenState.get(t); + System.out.println("tran = " + t.getFullLabel() + ", rate = " + tranRate); + } + } + System.out.println("--------------End Of Next Tran Rate Map----------------------"); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/Property.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/Property.java new file mode 100644 index 000000000..2a90c718c --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/Property.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.markovianAnalysis; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Property { + private String label; + + private String property; + + public Property(String label, String property) { + this.label = label; + this.property = property; + } + + String getLabel() { + return label; + } + + String getProperty() { + return property; + } + + /* + private void setLabel(String label) { + this.label = label; + } + + private void setProperty(String property) { + this.property = property; + } + */ +} \ No newline at end of file diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/TransientMarkovMatrixMultiplyThread.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/TransientMarkovMatrixMultiplyThread.java new file mode 100644 index 000000000..762c45412 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/markovianAnalysis/TransientMarkovMatrixMultiplyThread.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.markovianAnalysis; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class TransientMarkovMatrixMultiplyThread extends Thread { + + private MarkovianAnalysis markovianAnalysis; + + private double Gamma, timeLimit; + + private int startIndex, endIndex, K; + + public TransientMarkovMatrixMultiplyThread(MarkovianAnalysis markovianAnalysis) { + super(markovianAnalysis); + this.markovianAnalysis = markovianAnalysis; + } + + public void start(int startIndex, int endIndex, double Gamma, double timeLimit, int K) { + this.timeLimit = timeLimit; + this.Gamma = Gamma; + this.startIndex = startIndex; + this.endIndex = endIndex; + this.K = K; + super.start(); + } + + @Override + public void run() { + markovianAnalysis.transientMarkovMatrixMultiplication(startIndex, endIndex, Gamma, timeLimit, K); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/DependentSet.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/DependentSet.java new file mode 100644 index 000000000..98311bd98 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/DependentSet.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.partialOrders; + +import java.util.HashSet; + +import edu.utah.ece.async.lema.verification.lpn.Transition; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class DependentSet { + HashSet dependent; + Transition seed; + boolean enabledTranIsDummy; + + public DependentSet(HashSet dependent, Transition enabledTran2, boolean enabledTranIsDummy) { + this.dependent = dependent; + this.seed = enabledTran2; + this.enabledTranIsDummy = enabledTranIsDummy; + } + + public HashSet getDependent() { + return dependent; + } + + public Transition getSeed() { + return seed; + } + + public boolean isEnabledTranDummy() { + return enabledTranIsDummy; + } + + /** + * For each transition in dependent, check its LPN index. + * @return the lowest LPN index found in the dependent set. + */ + public int getLowestLpnNumber(int highestLpnIndex) { + int lowestLpnIndex = highestLpnIndex; + for (Transition t: dependent) { + if (t.getLpn().getLpnIndex() < lowestLpnIndex) + lowestLpnIndex = t.getLpn().getLpnIndex(); + } + return lowestLpnIndex; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/DependentSetComparator.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/DependentSetComparator.java new file mode 100644 index 000000000..3e4e2e3b7 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/DependentSetComparator.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.partialOrders; + +import java.util.Comparator; +import java.util.HashMap; + +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.main.Options; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class DependentSetComparator implements Comparator{ + private HashMap tranFiringFreqMap; + int highestLpnIndex; + + public DependentSetComparator(HashMap tranFiringFreq, int maxLpnIndex) { + this.tranFiringFreqMap = tranFiringFreq; + this.highestLpnIndex = maxLpnIndex; + } + + @Override + public int compare(DependentSet dep0, DependentSet dep1) { + if (!dep0.isEnabledTranDummy() && dep1.isEnabledTranDummy()) { + return -1; + } + else if ((dep0.isEnabledTranDummy() && !dep1.isEnabledTranDummy()) || (dep0.isEnabledTranDummy() && dep1.isEnabledTranDummy())) + return 1; + else { // Neither dep0 nor dep1 contains dummy transitions. + if (!Options.getMarkovianModelFlag()) { // non-stochastic +// // Compare sets with only immediate transitions and sets with only non-immediate ones. +// // Only need to compare seed transitions because a set with mixed immediate +// // and non-immediate transitions should not exist. +// if (dep0.getSeed().getDelayTree() == null && dep1.getSeed().getDelayTree() != null) +// return -1; +// // TODO: Immediate transition should have 0 delay, not "null" delay. +// else if (dep1.getSeed().getDelayTree() == null && dep0.getSeed().getDelayTree() != null) +// return 1; +// else { + if (dep0.getDependent().size() < dep1.getDependent().size()) + return -1; + else if (dep0.getDependent().size() > dep1.getDependent().size()) + return 1; + else { + if (tranFiringFreqMap.get(dep0.getSeed()) < tranFiringFreqMap.get(dep1.getSeed())) + return -1; + else if (tranFiringFreqMap.get(dep0.getSeed()) > tranFiringFreqMap.get(dep1.getSeed())) + return 1; + else { + if (dep0.getLowestLpnNumber(highestLpnIndex) < dep1.getLowestLpnNumber(highestLpnIndex)) + return -1; + else if (dep0.getLowestLpnNumber(highestLpnIndex) > dep1.getLowestLpnNumber(highestLpnIndex)) + return 1; + else + return 0; + } +// if (dep0.getLowestLpnNumber(highestLpnIndex) < dep1.getLowestLpnNumber(highestLpnIndex)) // +// return -1; +// else if (dep0.getLowestLpnNumber(highestLpnIndex) > dep1.getLowestLpnNumber(highestLpnIndex)) +// return 1; +// else { +// if (tranFiringFreqMap.get(dep0.getSeed()) < tranFiringFreqMap.get(dep1.getSeed())) +// return -1; +// else if (tranFiringFreqMap.get(dep1.getSeed()) < tranFiringFreqMap.get(dep0.getSeed())) +// return 1; +// else +// return 0; +// } + } +// } + } + // TODO: Add condition to compare the average transition rates. + return 0; + } + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/ProbStaticDependencySets.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/ProbStaticDependencySets.java new file mode 100644 index 000000000..7a4a8713b --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/ProbStaticDependencySets.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.partialOrders; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import edu.utah.ece.async.lema.verification.lpn.ExprTree; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.lpn.LpnDecomposition.LpnProcess; +import edu.utah.ece.async.lema.verification.platu.main.Options; + +/** + * This class extends the non-probabilistic static dependency transition set. + * It adds two more sets for dependency relations when transition rate expression is considered. + * + * @author Zhen Zhang + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ProbStaticDependencySets extends StaticDependencySets { + + /** + * The set of transitions whose transition rates can be changed by executing seedTran. + */ + private HashSet seedTranModifyOtherTranRate; + + /** + * The set of transitions that can potentially change seedTran's rate. + */ + private HashSet otherTransModifySeedTranRate; + + public ProbStaticDependencySets(Transition seedTran, + HashMap allTransToLpnProcs) { + super(seedTran, allTransToLpnProcs); + seedTranModifyOtherTranRate = new HashSet(); + otherTransModifySeedTranRate = new HashSet(); + } + + /** + * Construct a set of transitions. The transition rate of each transition in this set can potentially be modified by seedTran's assignment(s). + */ + public void buildSeedTranModifyOtherTransRatesSet() { + // This excludes any transitions that are in the same process as seedTran, and the process is a state machine. + if (!seedTran.getAssignments().isEmpty()) { + Set assignedVarNames = seedTran.getAssignments().keySet(); + ArrayList transInOneStateMachine = new ArrayList(); + if (allTransToLpnProcs.get(seedTran).getStateMachineFlag()) { + transInOneStateMachine = allTransToLpnProcs.get(seedTran).getProcessTransitions(); + } + for (Transition anotherTran : allTransToLpnProcs.keySet()) { + if (seedTran.equals(anotherTran) || transInOneStateMachine.contains(anotherTran)) + continue; + ExprTree anotherTranDelayTree = anotherTran.getDelayTree(); + if (anotherTranDelayTree != null) { + for (String var : assignedVarNames) { + if (anotherTranDelayTree.containsVar(var)) { + seedTranModifyOtherTranRate.add(anotherTran); + break; + } + } + } + } + } + //disableSet.addAll(seedTranModifyOtherTranRate); + } + + /** + * Construct a set of transitions. Each transition in this set can potentially modify seedTran's transition rate. + */ + public void buildOtherTransModifySeedTranRateSet() { + // This excludes any transitions that are in the same process as seedTran, and the process is a state machine. + ArrayList transInOneStateMachine = new ArrayList(); + if (allTransToLpnProcs.get(seedTran).getStateMachineFlag()) { + transInOneStateMachine = allTransToLpnProcs.get(seedTran).getProcessTransitions(); + } + for (Transition anotherTran : allTransToLpnProcs.keySet()) { + if (seedTran.equals(anotherTran) || transInOneStateMachine.contains(anotherTran)) + continue; + if (!anotherTran.getAssignments().isEmpty()) { + ExprTree seedTranDelayTree = seedTran.getDelayTree(); + if (seedTranDelayTree != null) { + Set assignedVarNames = anotherTran.getAssignments().keySet(); + for (String var : assignedVarNames) { + if (seedTranDelayTree.containsVar(var)) { + otherTransModifySeedTranRate.add(anotherTran); + break; + } + } + if (Options.getDebugMode()) { +// writeStringWithEndOfLineToPORDebugFile(seedTran.getLpn().getLabel() + "(" + seedTran.getLabel() + ") can be disabled by " + anotherTran.getLpn().getLabel() + "(" + anotherTran.getLabel() + "). " +// + seedTran.getLabel() + "'s enabling condition (" + seedTranDelayTree + "), may become false due to firing of " +// + anotherTran.getLabel() + "."); +// if (seedTranDelayTree.getChange(anotherTran.getAssignments())=='F') +// writeStringWithEndOfLineToPORDebugFile("Reason is " + seedTran.getLabel() + "_enablingTree.getChange(" + anotherTran.getLabel() + ".getAssignments()) = F."); +// if (seedTranDelayTree.getChange(anotherTran.getAssignments())=='f') +// writeStringWithEndOfLineToPORDebugFile("Reason is " + seedTran.getLabel() + "_enablingTree.getChange(" + anotherTran.getLabel() + ".getAssignments()) = f."); +// if (seedTranDelayTree.getChange(anotherTran.getAssignments())=='X') +// writeStringWithEndOfLineToPORDebugFile("Reason is " + seedTran.getLabel() + "_enablingTree.getChange(" + anotherTran.getLabel() + ".getAssignments()) = X."); + } + otherTransModifySeedTranRate.add(anotherTran); + } + } + } + //disableSet.addAll(otherTransModifySeedTranRate); + } + + @Override + public HashSet getDisableSet(boolean seedTranIsPersistent) { + HashSet disableSet = new HashSet(); + disableSet.addAll(getSeedTranDisableOtherTrans()); + disableSet.addAll(getOtherTransDisableSeedTran(seedTranIsPersistent)); + disableSet.addAll(seedTranModifyOtherTranRate); + disableSet.addAll(otherTransModifySeedTranRate); + return disableSet; + } + + @Override + public HashSet getOtherTransDisableSeedTran(boolean persistentTranEnabled) { + HashSet otherTransDisableSeedTran = new HashSet(); + if (!persistentTranEnabled) { + otherTransDisableSeedTran.addAll(otherTransSetSeedTranEnablingFalse); + } + otherTransDisableSeedTran.addAll(disableByStealingToken); + otherTransDisableSeedTran.addAll(otherTransModifySeedTranAssign); + otherTransDisableSeedTran.addAll(seedTranOtherTransModifySameVars); + otherTransDisableSeedTran.addAll(otherTransModifySeedTranRate); + return otherTransDisableSeedTran; + } + + @Override + public HashSet getSeedTranDisableOtherTrans() { + HashSet seedTranDisableOtherTransSet = new HashSet(); + seedTranDisableOtherTransSet.addAll(disableByStealingToken); + seedTranDisableOtherTransSet.addAll(seedTranSetOtherTranEnablingFalse); + seedTranDisableOtherTransSet.addAll(seedTranModifyOtherTranAssign); + seedTranDisableOtherTransSet.addAll(seedTranOtherTransModifySameVars); + seedTranDisableOtherTransSet.addAll(seedTranModifyOtherTranRate); + return seedTranDisableOtherTransSet; + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/StaticDependencySets.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/StaticDependencySets.java new file mode 100644 index 000000000..ab918d8b9 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/partialOrders/StaticDependencySets.java @@ -0,0 +1,553 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.partialOrders; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +import edu.utah.ece.async.lema.verification.lpn.ExprTree; +import edu.utah.ece.async.lema.verification.lpn.Place; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.lpn.LpnDecomposition.LpnProcess; +import edu.utah.ece.async.lema.verification.platu.main.Options; + +/** + * This class is used for constructing static dependent transition set for each seed transition. + * @author Zhen Zhang + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class StaticDependencySets { + protected Transition seedTran; + //protected HashSet disableSet; + protected HashSet disableByStealingToken; + + /** + * All transitions whose enabling condition can be evaluated to true if seedTran is executed. + */ + protected ArrayList> otherTransSetSeedTranEnablingTrue; + /** + * All transitions whose enabling condition can be evaluated to false if seedTran is executed. + */ + protected HashSet seedTranSetOtherTranEnablingFalse; + + /** + * All transitions that can potentially set seedTran's enabling condition to false. + */ + protected HashSet otherTransSetSeedTranEnablingFalse; + + protected HashSet seedTranModifyOtherTranAssign; + + protected HashSet otherTransModifySeedTranAssign; + + protected HashSet seedTranOtherTransModifySameVars; + + + private String PORdebugFileName; + private FileWriter PORdebugFileStream; + private BufferedWriter PORdebugBufferedWriter; + protected HashMap allTransToLpnProcs; + // ---- Specific field variables for probabilistic models ---- + //private HashSet seedTranModifyOtherTranRate; + //private ArrayList> otherTransModifySeedTranRate; + // -------------------------------------------------- + + public StaticDependencySets(Transition seedTran, HashMap allTransToLpnProcs) { + this.seedTran = seedTran; + this.allTransToLpnProcs = allTransToLpnProcs; + //disableSet = new HashSet(); + disableByStealingToken = new HashSet(); + otherTransSetSeedTranEnablingTrue = new ArrayList>(); + seedTranSetOtherTranEnablingFalse = new HashSet(); + otherTransSetSeedTranEnablingFalse = new HashSet(); + seedTranModifyOtherTranAssign = new HashSet(); + otherTransModifySeedTranAssign = new HashSet(); + seedTranOtherTransModifySameVars = new HashSet(); + + if (Options.getDebugMode()) { + PORdebugFileName = Options.getPrjSgPath() + Options.getLogName() + "_" + Options.getPOR() + "_" + + Options.getCycleClosingMthd() + "_" + Options.getCycleClosingStrongStubbornMethd() + ".dbg"; + try { + PORdebugFileStream = new FileWriter(PORdebugFileName, true); + } catch (IOException e) { + e.printStackTrace(); + } + PORdebugBufferedWriter = new BufferedWriter(PORdebugFileStream); + } + } + + /** + * Build the set of transitions whose enabling condition can be set to false by executing seedTran. + */ + public void buildSeedTranSetOtherTranEnablingFalse() { + // Test if seedTran can disable other transitions by executing its assignments. + // This excludes any transitions that are in the same process as seedTran, and the process is a state machine. + if (!seedTran.getAssignments().isEmpty()) { + ArrayList transInOneStateMachine = new ArrayList(); + if (allTransToLpnProcs.get(seedTran).getStateMachineFlag()) { + transInOneStateMachine = allTransToLpnProcs.get(seedTran).getProcessTransitions(); + } + for (Transition anotherTran : allTransToLpnProcs.keySet()) { + if (seedTran.equals(anotherTran) || transInOneStateMachine.contains(anotherTran)) + continue; + ExprTree anotherTranEnablingTree = anotherTran.getEnablingTree(); + if (anotherTranEnablingTree != null + && (anotherTranEnablingTree.getChange(seedTran.getAssignments())=='F' + || anotherTranEnablingTree.getChange(seedTran.getAssignments())=='f' + || anotherTranEnablingTree.getChange(seedTran.getAssignments())=='X')) { + if (Options.getDebugMode()) { + writeStringWithEndOfLineToPORDebugFile(seedTran.getLpn().getLabel() + "(" + seedTran.getLabel() + ") can disable " + anotherTran.getLpn().getLabel() + "(" + anotherTran.getLabel() + "). " + + anotherTran.getLabel() + "'s enabling condition (" + anotherTranEnablingTree + "), may become false due to firing of " + + seedTran.getLabel() + "."); + if (anotherTranEnablingTree.getChange(seedTran.getAssignments())=='F') + writeStringWithEndOfLineToPORDebugFile("Reason is " + anotherTran.getLabel() + "_enablingTree.getChange(" + seedTran.getLabel() + ".getAssignments()) = F."); + if (anotherTranEnablingTree.getChange(seedTran.getAssignments())=='f') + writeStringWithEndOfLineToPORDebugFile("Reason is " + anotherTran.getLabel() + "_enablingTree.getChange(" + seedTran.getLabel() + ".getAssignments()) = f."); + if (anotherTranEnablingTree.getChange(seedTran.getAssignments())=='X') + writeStringWithEndOfLineToPORDebugFile("Reason is " + anotherTran.getLabel() + "_enablingTree.getChange(" + seedTran.getLabel() + ".getAssignments()) = X."); + } + seedTranSetOtherTranEnablingFalse.add(anotherTran); + } + } + } + } + + /** + * Build a set of transitions that may disable seedTran. + */ + public void buildOtherTransDisableSeedTran() { + buildDisableByStealingToken(); + buildOtherTransModifySeedTranAssign(); + buildSeedTranOtherTransModifySameVars(); + buildOtherTransSetSeedTranEnablingFalse(); + } + + /** + * Build a set of transitions that seedTran can disable. + */ + public void buildSeedTranDisableOtherTrans() { + buildDisableByStealingToken(); + buildSeedTranModifyOtherTransAssign(); + buildSeedTranOtherTransModifySameVars(); + buildSeedTranSetOtherTranEnablingFalse(); + } + + public void buildOtherTransSetSeedTranEnablingFalse() { + // Test if other transitions can disable seedTran by executing their assignments. + // If seedTran's process is a state machine, this set excludes any transitions that are in the same process as seedTran. + ArrayList transInOneStateMachine = new ArrayList(); + if (allTransToLpnProcs.get(seedTran).getStateMachineFlag()) { + transInOneStateMachine = allTransToLpnProcs.get(seedTran).getProcessTransitions(); + } + for (Transition anotherTran : allTransToLpnProcs.keySet()) { + if (seedTran.equals(anotherTran) || transInOneStateMachine.contains(anotherTran)) + continue; + if (!anotherTran.getAssignments().isEmpty()) { + ExprTree seedTranEnablingTree = seedTran.getEnablingTree(); + if (seedTranEnablingTree != null + && (seedTranEnablingTree.getChange(anotherTran.getAssignments())=='F' + || seedTranEnablingTree.getChange(anotherTran.getAssignments())=='f' + || seedTranEnablingTree.getChange(anotherTran.getAssignments())=='X')) { + if (Options.getDebugMode()) { + writeStringWithEndOfLineToPORDebugFile(seedTran.getLpn().getLabel() + "(" + seedTran.getLabel() + ") can be disabled by " + anotherTran.getLpn().getLabel() + "(" + anotherTran.getLabel() + "). " + + seedTran.getLabel() + "'s enabling condition (" + seedTranEnablingTree + "), may become false due to firing of " + + anotherTran.getLabel() + "."); + if (seedTranEnablingTree.getChange(anotherTran.getAssignments())=='F') + writeStringWithEndOfLineToPORDebugFile("Reason is " + seedTran.getLabel() + "_enablingTree.getChange(" + anotherTran.getLabel() + ".getAssignments()) = F."); + if (seedTranEnablingTree.getChange(anotherTran.getAssignments())=='f') + writeStringWithEndOfLineToPORDebugFile("Reason is " + seedTran.getLabel() + "_enablingTree.getChange(" + anotherTran.getLabel() + ".getAssignments()) = f."); + if (seedTranEnablingTree.getChange(anotherTran.getAssignments())=='X') + writeStringWithEndOfLineToPORDebugFile("Reason is " + seedTran.getLabel() + "_enablingTree.getChange(" + anotherTran.getLabel() + ".getAssignments()) = X."); + } + otherTransSetSeedTranEnablingFalse.add(anotherTran); + } + } + } + } + + /** + * Construct the set of transitions that may disable seedTran by stealing its preset token. + */ + public void buildDisableByStealingToken() { + // To avoid duplicated calls for this method, i.e.buildOtherTransDisableSeedTran and buildSeedTranDisableOtherTrans, + // only proceed to build the disableByStealingToken set if it is not empty. + if (!disableByStealingToken.isEmpty()) { + if (seedTran.hasConflict()) { + if (!isSelfLoop()) { + if (allTransToLpnProcs.get(seedTran).getStateMachineFlag()) { + outerloop:for (Transition tranInConflict : seedTran.getConflictSet()) { + // In a state machine, if tranInConflict and seedTran have disjoint enabling conditions, + // they are not dependent on each other. + // Temporary solution: compare each conjunct to decide if they are disjoint. + // Each conjunct in comparison only allows single literal or the negation of a literal. + // TODO: Need a (DPLL) SAT solver to decide if they are disjoint. + if (seedTran.getConjunctsOfEnabling() != null && !seedTran.getConjunctsOfEnabling().isEmpty()) { + for (ExprTree conjunctOfSeedTran : seedTran.getConjunctsOfEnabling()) { + for (ExprTree conjunctOfTranInConflict : tranInConflict.getConjunctsOfEnabling()) { + if (conjunctOfSeedTran.getVars().size()==1 && conjunctOfTranInConflict.getVars().size()==1 + && conjunctOfSeedTran.getVars().equals(conjunctOfTranInConflict.getVars())) { + ExprTree clause = new ExprTree(conjunctOfSeedTran, conjunctOfTranInConflict, "&&", 'l'); + HashMap assign = new HashMap(); + assign.put(conjunctOfSeedTran.getVars().get(0), "0"); + if (clause.evaluateExpr(assign) == 0.0) { + assign.put(conjunctOfSeedTran.getVars().get(0), "1"); + if (clause.evaluateExpr(assign) == 0.0) { + continue outerloop; + } + } + } + } + } + } + disableByStealingToken.add(tranInConflict); + } + } + else { + for (Transition tranInConflict : seedTran.getConflictSet()) { + disableByStealingToken.add(tranInConflict); + } + } + } + if (Options.getDebugMode()) { + writeStringWithEndOfLineToPORDebugFile(seedTran.getLpn().getLabel() + "(" + seedTran.getLabel() + ") can cause dependency relation by stealing tokens from these transitions:"); + for (Transition t : disableByStealingToken) { + writeStringToPORDebugFile(t.getLpn().getLabel() + "(" + t.getLabel() + "), "); + } + writeStringWithEndOfLineToPORDebugFile(""); + } + } + } + } + + private boolean isSelfLoop() { + boolean isSelfLoop = false; + Place[] seedPreset = seedTran.getPreset(); + Place[] seedPostset = seedTran.getPostset(); + for (Place preset : seedPreset) { + for (Place postset : seedPostset) { + if (preset == postset) { + isSelfLoop = true; + break; + } + } + if (isSelfLoop) + break; + } + return isSelfLoop; + } + +// /** +// * Construct a set of transitions that can make the enabling condition of seedTran true, by executing their assignments. +// */ +// public void buildEnableBySettingEnablingTrue() { +// for (Integer lpnIndex : allTransitions.keySet()) { +// Transition[] allTransInOneLpn = allTransitions.get(lpnIndex); +// for (int i = 0; i < allTransInOneLpn.length; i++) { +// if (curTran.equals(allTransInOneLpn[i])) +// continue; +// Transition anotherTran = allTransInOneLpn[i]; +// ExprTree curTranEnablingTree = curTran.getEnablingTree(); +// if (curTranEnablingTree != null +// && (curTranEnablingTree.getChange(anotherTran.getAssignments())=='T' +// || curTranEnablingTree.getChange(anotherTran.getAssignments())=='t' +// || curTranEnablingTree.getChange(anotherTran.getAssignments())=='X')) { +// enableBySettingEnablingTrue.add(new Transition(lpnIndex, anotherTran.getIndex())); +// if (Options.getDebugMode()) { +// writeStringWithEndOfLineToPORDebugFile(curTran.getName() + " can be enabled by " + anotherTran.getName() + ". " +// + curTran.getName() + "'s enabling condition (" + curTranEnablingTree + "), may become true due to firing of " +// + anotherTran.getName() + "."); +// if (curTranEnablingTree.getChange(anotherTran.getAssignments())=='T') +// writeStringWithEndOfLineToPORDebugFile("Reason is " + curTran.getName() + "_enablingTree.getChange(" + anotherTran.getName() + ".getAssignments()) = T."); +// if (curTranEnablingTree.getChange(anotherTran.getAssignments())=='t') +// writeStringWithEndOfLineToPORDebugFile("Reason is " + curTran.getName() + "_enablingTree.getChange(" + anotherTran.getName() + ".getAssignments()) = t."); +// if (curTranEnablingTree.getChange(anotherTran.getAssignments())=='X') +// writeStringWithEndOfLineToPORDebugFile("Reason is " + curTran.getName() + "_enablingTree.getChange(" + anotherTran.getName() + ".getAssignments()) = X."); +// } +// } +// } +// } +// } + +// public void buildModifyAssignSet() { +//// for every transition curTran in T, where T is the set of all transitions, we check t (t != curTran) in T, +//// (1) intersection(VA(curTran), supportA(t)) != empty +//// (2) intersection(VA(t), supportA(curTran)) != empty +//// (3) intersection(VA(t), VA(curTran) != empty +//// +//// VA(t0) : set of variables being assigned to (left hand side of the assignment) in transition t0. +//// supportA(t0): set of variables appearing in the expressions assigned to the variables of t0 (right hand side of the assignment). +// for (Integer lpnIndex : allTransitions.keySet()) { +// Transition[] allTransInOneLpn = allTransitions.get(lpnIndex); +// for (int i = 0; i < allTransInOneLpn.length; i++) { +// if (curTran.equals(allTransInOneLpn[i])) +// continue; +// Transition anotherTran = allTransInOneLpn[i]; +// for (String v : curTran.getAssignTrees().keySet()) { +// for (ExprTree anotherTranAssignTree : anotherTran.getAssignTrees().values()) { +// if (anotherTranAssignTree != null && anotherTranAssignTree.containsVar(v)) { +// modifyAssignment.add(new Transition(lpnIndex, anotherTran.getIndex())); +// if (Options.getDebugMode()) { +//// System.out.println("Variable " + v + " in " + curTran.getName() +//// + " may change the right hand side of assignment " + anotherTranAssignTree + " in " + anotherTran.getName()); +// } +// } +// } +// } +// for (ExprTree curTranAssignTree : curTran.getAssignTrees().values()) { +// for (String v : anotherTran.getAssignTrees().keySet()) { +// if (curTranAssignTree != null && curTranAssignTree.containsVar(v)) { +// modifyAssignment.add(new Transition(lpnIndex, anotherTran.getIndex())); +// if (Options.getDebugMode()) { +//// System.out.println("Variable " + v + " in " + anotherTran.getName() +//// + " may change the right hand side of assignment " + curTranAssignTree + " in " + anotherTran.getName()); +// } +// } +// } +// } +// for (String v1 : curTran.getAssignTrees().keySet()) { +// for (String v2 : anotherTran.getAssignTrees().keySet()) { +// if (v1.equals(v2)) { +// modifyAssignment.add(new Transition(lpnIndex, anotherTran.getIndex())); +// if (Options.getDebugMode()) { +//// System.out.println("Variable " + v1 + " are assigned in " + curTran.getName() + " and " + anotherTran.getName()); +// } +// } +// } +// } +// } +// } +// } + /** + * Construct a set of transitions that can make the enabling condition of curTran true, by executing their assignments. + */ + public void buildOtherTransSetSeedTranEnablingTrue() { + ExprTree seedTranEnablingTree = seedTran.getEnablingTree(); + if (seedTranEnablingTree != null) {// || curTranEnablingTree.toString().equals("TRUE") || curTranEnablingTree.toString().equals("FALSE"))) { + if (Options.getDebugMode()) { + writeStringWithEndOfLineToPORDebugFile("Transition " + seedTran.getLpn().getLabel() + "(" + seedTran.getLabel() + ")'s enabling tree is " + seedTranEnablingTree.toString() + " and getOp() returns " + seedTranEnablingTree.getOp()); + writeStringWithEndOfLineToPORDebugFile(seedTran.getLpn().getLabel() + "(" + seedTran.getLabel() + ")'s enabling transition has the following terms: "); + if (seedTran.getConjunctsOfEnabling() != null){ + for (int i1=0; i1 transCanEnableConjunct = new HashSet(); + for (Transition anotherTran : allTransToLpnProcs.keySet()) { + if (seedTran.equals(anotherTran)) + continue; + if (conjunct.getChange(anotherTran.getAssignments())=='T' + || conjunct.getChange(anotherTran.getAssignments())=='t' + || conjunct.getChange(anotherTran.getAssignments())=='X') { + transCanEnableConjunct.add(anotherTran); + if (Options.getDebugMode()) { + writeStringWithEndOfLineToPORDebugFile(seedTran.getLpn().getLabel() + "(" + seedTran.getLabel() + ")'s conjunct (" + conjunct.toString() + ") in its enabling condition (" + seedTranEnablingTree + + ") can be set to true by " + anotherTran.getLabel() + ". "); + if (conjunct.getChange(anotherTran.getAssignments())=='T') + writeStringWithEndOfLineToPORDebugFile("The reason is conjunct.getChange(" + anotherTran.getLabel() + ".getAssignments()) = T."); + if (conjunct.getChange(anotherTran.getAssignments())=='t') + writeStringWithEndOfLineToPORDebugFile("The reason is conjunct.getChange(" + anotherTran.getLabel() + ".getAssignments()) = t."); + if (conjunct.getChange(anotherTran.getAssignments())=='X') + writeStringWithEndOfLineToPORDebugFile("The reason is conjunct.getChange(" + anotherTran.getLabel() + ".getAssignments()) = X."); + } + } + } + otherTransSetSeedTranEnablingTrue.add(index, transCanEnableConjunct); + } + } + } + } + + public HashSet getOtherTransDisableSeedTran(boolean persistentTranEnabled) { + HashSet otherTransDisableSeedTran = new HashSet(); + if (!persistentTranEnabled) { + otherTransDisableSeedTran.addAll(otherTransSetSeedTranEnablingFalse); + } + otherTransDisableSeedTran.addAll(disableByStealingToken); + otherTransDisableSeedTran.addAll(otherTransModifySeedTranAssign); + otherTransDisableSeedTran.addAll(seedTranOtherTransModifySameVars); + return otherTransDisableSeedTran; + } + + public HashSet getSeedTranDisableOtherTrans() { + HashSet seedTranDisableOtherTransSet = new HashSet(); + seedTranDisableOtherTransSet.addAll(disableByStealingToken); + seedTranDisableOtherTransSet.addAll(seedTranSetOtherTranEnablingFalse); + seedTranDisableOtherTransSet.addAll(seedTranModifyOtherTranAssign); + seedTranDisableOtherTransSet.addAll(seedTranOtherTransModifySameVars); + return seedTranDisableOtherTransSet; + } + + public HashSet getDisableSet(boolean seedTranIsPersistent) { + HashSet disableSet = new HashSet(); + disableSet.addAll(getSeedTranDisableOtherTrans()); + disableSet.addAll(getOtherTransDisableSeedTran(seedTranIsPersistent)); + return disableSet; + } + + public ArrayList> getOtherTransSetSeedTranEnablingTrue() { + return otherTransSetSeedTranEnablingTrue; + } + + public Transition getSeedTran() { + return seedTran; + } + + /** + * For every transition t other than the seedTran, add it to seedTranModifyOtherTranAssign if

+ * + intersection(VA(t), assignExp(seedTran)) != empty,

+ + where VA(t0) is the set of variables being assigned to (left hand side of the assignment) in transition t0, and
+ assignExp(t0) is the set of variables appearing in t0's every assignment expression (right hand side of an assignment). + */ + public void buildSeedTranModifyOtherTransAssign() { + ArrayList transInOneStateMachine = new ArrayList(); + if (allTransToLpnProcs.get(seedTran).getStateMachineFlag()) { + transInOneStateMachine = allTransToLpnProcs.get(seedTran).getProcessTransitions(); + } + for (Transition anotherTran : allTransToLpnProcs.keySet()) { + if (seedTran.equals(anotherTran) || transInOneStateMachine.contains(anotherTran)) + // seedTran does not have "modify assignments" problem with all transitions in the same process, if the process is a state machine. + continue; + for (String v : seedTran.getAssignTrees().keySet()) { + for (ExprTree anotherTranAssignTree : anotherTran.getAssignTrees().values()) { + if (anotherTranAssignTree != null && anotherTranAssignTree.containsVar(v)) { + seedTranModifyOtherTranAssign.add(anotherTran); + if (Options.getDebugMode()) { + writeStringWithEndOfLineToPORDebugFile("Variable " + v + " in " + seedTran.getLpn().getLabel() + "(" + seedTran.getLabel() + ")" + + " may change the right hand side of assignment " + anotherTranAssignTree + " in " + anotherTran.getLabel()); + } + } + } + } + } + } + + /** + * For every transition t other than the seedTran, add it to otherTransModifySeedTranAssign if

+ intersection(VA(seedTran), assignExp(t)) != empty

+ + where VA(t0) is the set of variables being assigned to (left hand side of the assignment) in transition t0, and
+ assignExp(t0) is the set of variables appearing in t0's every assignment expression (right hand side of an assignment). + */ + public void buildOtherTransModifySeedTranAssign() { + ArrayList transInOneStateMachine = new ArrayList(); + if (allTransToLpnProcs.get(seedTran).getStateMachineFlag()) { + transInOneStateMachine = allTransToLpnProcs.get(seedTran).getProcessTransitions(); + } + for (Transition anotherTran : allTransToLpnProcs.keySet()) { + if (seedTran.equals(anotherTran) || transInOneStateMachine.contains(anotherTran)) + // seedTran does not have "modify assignments" problem with all transitions in the same process, if the process is a state machine. + continue; + for (ExprTree seedTranAssignTree : seedTran.getAssignTrees().values()) { + for (String v : anotherTran.getAssignTrees().keySet()) { + if (seedTranAssignTree != null && seedTranAssignTree.containsVar(v)) { + otherTransModifySeedTranAssign.add(anotherTran); + if (Options.getDebugMode()) { + writeStringWithEndOfLineToPORDebugFile("Variable " + v + " in " + anotherTran.getLpn().getLabel() + "(" + anotherTran.getLabel() + ")" + + " may change the right hand side of assignment " + seedTranAssignTree + " in " + anotherTran.getLabel()); + } + } + } + } + } + } + + /** + * For every transition t other than the seedTran, add it to seedTranOtherTransModifySameVars if

+ intersection(VA(t), VA(seedTran) != empty

+ + where VA(t0) is the set of variables being assigned to (left hand side of the assignment) in transition t0, and
+ assignExp(t0) is the set of variables appearing in t0's every assignment expression (right hand side of an assignment). + */ + public void buildSeedTranOtherTransModifySameVars() { + // To avoid duplicated calls for this method, i.e.buildOtherTransDisableSeedTran and buildSeedTranDisableOtherTrans, + // only proceed to build the seedTranOtherTransModifySameVars set if it is not empty. + if (seedTranOtherTransModifySameVars.isEmpty()) { + ArrayList transInOneStateMachine = new ArrayList(); + if (allTransToLpnProcs.get(seedTran).getStateMachineFlag()) { + transInOneStateMachine = allTransToLpnProcs.get(seedTran).getProcessTransitions(); + } + for (Transition anotherTran : allTransToLpnProcs.keySet()) { + if (seedTran.equals(anotherTran) || transInOneStateMachine.contains(anotherTran)) + // seedTran does not have "modify assignments" problem with all transitions in the same process, if the process is a state machine. + continue; + for (String v1 : seedTran.getAssignTrees().keySet()) { + for (String v2 : anotherTran.getAssignTrees().keySet()) { + if (v1.equals(v2) && !seedTran.getAssignTree(v1).equals(anotherTran.getAssignTree(v2))) { + seedTranOtherTransModifySameVars.add(anotherTran); + if (Options.getDebugMode()) { + writeStringWithEndOfLineToPORDebugFile("Variable " + v1 + " are assigned in " + seedTran.getLpn().getLabel() + "(" + seedTran.getLabel() + ") and " + anotherTran.getLpn().getLabel() + "(" + anotherTran.getLabel() + ")"); + } + } + } + } + } + } + } + + protected void writeStringWithEndOfLineToPORDebugFile(String string) { + try { + PORdebugBufferedWriter.append(string); + PORdebugBufferedWriter.newLine(); + PORdebugBufferedWriter.flush(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void writeStringToPORDebugFile(String string) { + try { + PORdebugBufferedWriter.append(string); + + PORdebugBufferedWriter.flush(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +// public HashSet getEnableSet() { +// HashSet enableSet = new HashSet(); +// enableSet.addAll(enableByBringingToken); +// enableSet.addAll(enableBySettingEnablingTrue); +// return enableSet; +// } + +// private void printIntegerSet(HashSet integerSet, String setName) { +// if (!setName.isEmpty()) +// System.out.print(setName + ": "); +// if (integerSet == null) { +// System.out.println("null"); +// } +// else if (integerSet.isEmpty()) { +// System.out.println("empty"); +// } +// else { +// for (Iterator seedTranDisableIter = integerSet.iterator(); seedTranDisableIter.hasNext();) { +// Integer tranInDisable = seedTranDisableIter.next(); +// System.out.print(lpn.getAllTransitions()[tranInDisable] + " "); +// } +// System.out.print("\n"); +// } +// } + } diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/DualHashMap.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/DualHashMap.java new file mode 100644 index 000000000..04fa8f846 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/DualHashMap.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.platuLpn; + +import java.util.HashMap; +import java.util.Map.Entry; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class DualHashMap extends HashMap { + private static final long serialVersionUID = 239875623984691837L; + HashMap ValueMap; + + public DualHashMap(int size) { + super(size); + ValueMap = new HashMap(size); + } + + public DualHashMap() { + ValueMap = new HashMap(); + } + + public DualHashMap(HashMap other) { + ValueMap = new HashMap(other.size()); + for (Entry e : other.entrySet()) { + insert(e.getKey(), e.getValue()); + } + } + + public DualHashMap(HashMap other, int size) { + super(size); + ValueMap = new HashMap(size); + for (Entry e : other.entrySet()) { + insert(e.getKey(), e.getValue()); + } + } + + /** + * Adds a pair into the dual hash map. This will override existing key and value pairs. + * @param key + * @param value + */ + public void insert(Key key, Value value) { + put(key, value); + ValueMap.put(value, key); + } + + /** + * Removes the mapping associated with the Key. + * @param key + */ + public void delete(Key key) { + Value v = remove(key); + ValueMap.remove(v); + } + + /** + * @param value Value associated with key. + * @return Key associated with the specified value, otherwise null. + */ + public Key getKey(Value value) { + return ValueMap.get(value); + } + + /** + * @param key Key associated with value. + * @return Returns the value associated with the specified key, otherwise null. + */ + public Value getValue(Key key) { + return get(key); + } + + @Override + public DualHashMap clone(){ + DualHashMap copy = new DualHashMap(); + for(Entry e : this.entrySet()){ + copy.insert(e.getKey(), e.getValue()); + } + + return copy; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/LPNTran.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/LPNTran.java new file mode 100644 index 000000000..f2c93ce99 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/LPNTran.java @@ -0,0 +1,819 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.platuLpn; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; + +import edu.utah.ece.async.lema.verification.platu.TimingAnalysis.Zone1; +import edu.utah.ece.async.lema.verification.platu.expression.Expression; +import edu.utah.ece.async.lema.verification.platu.expression.VarNode; +import edu.utah.ece.async.lema.verification.platu.platuLpn.PlatuLPN; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class LPNTran { + + public static final int[] toArray(Collection set) { + int[] arr = new int[set.size()]; + int idx = 0; + for (int i : set) { + arr[idx++] = i; + } + return arr; + } + + /* LPN where this transition is defined. */ + private PlatuLPN lpn; + + /* Transition labels in the same LPN must be unique. */ + private String label; + + /* Index of this transition in the this.lpn. */ + private int index; + + private int[] preSet; + private int[] postSet; + + private Expression enablingGuard; // Enabling condition + + private VarExprList assignments = new VarExprList(); + + private int delayLB; // Lower bound of the delay + private int delayUB; // Upper bound of the delay. + + /* Variables on LHS of assignments of this transition. */ + private HashSet assignedVarSet; + + /* Variables in the enablingGuard and in the expressions on RHS of assignments. */ + private HashSet supportSet; + + /* True if all variables in assignedVarSet are in the set 'internals' of this.lpn. */ + private boolean local = true; + + /* A set of Boolean formulas that should hold after firing this transition. */ + private ArrayList assertions = new ArrayList(1); + + /* LPNs that share variables in the assignedVarSet of this transition. */ + private List dstLpnList = new ArrayList(); + + /* true indicating this transition follows non-disabling semantics. */ + private boolean stickyFlag = true; + + public LPNTran(String Label, int index, Collection preSet, Collection postSet, + Expression enablingGuard, VarExprList assignments, int DelayLB, int DelayUB, boolean local) { + //this.lpnModel=lpnModel; + this.label = Label; + this.index = index; + this.preSet = toArray(preSet); + this.postSet = toArray(postSet); + this.enablingGuard = enablingGuard; + this.assignments = assignments; + this.delayLB = DelayLB; + this.delayUB = DelayUB; + this.local = local; + assignedVarSet = new HashSet(); + //nextStateMap = new HashMap(); + + if (preSet == null || postSet == null || enablingGuard == null || assignments == null) { + new NullPointerException().printStackTrace(); + } + } + + public LPNTran(String Label, int index, int[] preSet, int[] postSet, Expression enablingGuard, + VarExprList assignments, int DelayLB, int DelayUB, boolean local) { + this.label = Label; + this.index = index; + this.preSet = preSet; + this.postSet = postSet; + this.enablingGuard = enablingGuard; + this.assignments = assignments; + this.delayLB = DelayLB; + this.delayUB = DelayUB; + this.local = local; + assignedVarSet = new HashSet(); + //nextStateMap = new HashMap(); + + if (preSet == null || postSet == null || enablingGuard == null || assignments == null) { + new NullPointerException().printStackTrace(); + } + } + + public void initialize(final PlatuLPN lpnModel) { + // Computer the variables on the left hand side of the assignments. + this.lpn = lpnModel; + this.supportSet = new HashSet(); + + HashSet guardVarSet = this.enablingGuard.getVariables(); + for(VarNode var : guardVarSet){ + this.supportSet.add(var.getName()); + } + + // Determine the visibility of this tran. + for (VarExpr assign : this.assignments) { + assignedVarSet.add(assign.getVar()); + + HashSet tmp = assign.getExpr().getVariables(); + for(VarNode var : tmp){ + this.supportSet.add(var.getName()); + } + } + } + + public HashSet getAssignedVar() { + return this.assignedVarSet; + } + + public HashSet getSupportVar() { + return this.supportSet; + } + + // (done) Moved to StateGraph. + /** + * Check if firing 'fired_transition' causes a disabling error. + * @param current_enabled_transitions + * @param next_enabled_transitions + * @return + */ + public LPNTran disablingError( + final LinkedList current_enabled_transitions, + final LinkedList next_enabled_transitions) { + if (current_enabled_transitions == null || current_enabled_transitions.size()==0) + return null; + + for(LPNTran curTran : current_enabled_transitions) { + boolean disabled = true; + if (next_enabled_transitions != null && next_enabled_transitions.size()!=0) { + for(LPNTran nextTran : next_enabled_transitions) { + if(curTran == nextTran) { + disabled = false; + break; + } + } + } + + if (disabled == true) { + if(this.sharePreSet(curTran) == false) + return curTran; + } + } + + return null; + } + + static public LPNTran disablingError(final LinkedList current_enabled_transitions, final LinkedList next_enabled_transitions, LPNTran ths) { + return ths.disablingError(current_enabled_transitions, next_enabled_transitions); + } + + static public LPNTran disablingError(final LPNTran[] current_enabled_transitions, final LPNTran[] next_enabled_transitions,LPNTran ths) { + // current_enabled_transitions.remove(fired_transition); + // return current_enabled_transitions.containsAll(next_enabled_transitions); + + if (current_enabled_transitions == null) { + return null; + } + + for (LPNTran cet:current_enabled_transitions) { + if(cet == ths) + continue; + + boolean disabled = true; + if(next_enabled_transitions != null) { + for (LPNTran net:next_enabled_transitions) { + if (cet.label == net.label) { + disabled = false; + break; + } + } + } + + if (disabled == true) + if (ths.sharePreSet(cet)==false) + return cet; + } + + return null; + } + + final public boolean isEnabled(final State curState) { + if (curState == null) { + throw new NullPointerException(); + } + + if (this.preSet != null && this.preSet.length > 0) { + for (int pp : this.preSet) { + int[] curMarking = curState.getMarking(); + boolean included = false; + + for (int i = 0; i < curMarking.length; i++) { + if (curMarking[i] == pp) { + included = true; + break; + } + } + + if (included == false) + return false; + } + } + + int[] curVector = curState.getVariableVector(); + if (curVector.length > 0) { + if(getEnablingGuard().evaluate(curVector) == 0) + return false; + } + + return true; + } + + // Check if this LPN transition satisfies the timing constraint: its lower bound of delay + // is larger than the maximal value of its timed in curZone. + public boolean isTimedEnabled(final State curState, final Zone1 curZone) { + if(this.isEnabled(curState) == false) + return false; + + if (this.delayLB == 0) + return true; + + // Checking timing against the zone +// Integer timerMaxVal = 0;//curZone.get(0, this.getID()); +// return timerMaxVal == null ? true : this.delayLB <= timerMaxVal; + return false; + } + + public static boolean containsAll(Integer[] set1, int[] set2) { + int curMarkingSize = set1.length; + for (int prep : set2) { + boolean existed = false; + for (int index = 0; index < curMarkingSize; index++) { + if (set1[index] == prep) { + existed = true; + break; + } + } + if (existed == false) { + return false; + } + } + return true; + } + + static final public boolean notContainsAll(final int[] set1,final int[] set2) { + //return false if set2 is a subset of set1 + int index; + for (int i = 0; i < set2.length; i++) { + for ( index = 0; index < set1.length; index++) { + if (set1[index] == set2[i]) { + break; + } + } + if (index >= set1.length) { + return true; + } + } + return false; + } + + static final public boolean containsAll(int[] set1, int[] set2) { + int index; for (int i = 0; i < set2.length; i++) { + boolean exists = false; + for ( index = 0; index < set1.length; index++) { + if (set1[index] == set2[i]) { + exists = true; + break; + } + } + if (exists == false) { + return false; + } + } + return true; + } + + + + final public boolean sharePreSet(final LPNTran other) { + for (int i : preSet) { + for (int j : other.preSet) { + if (i == j) { + return true; + } + } + } + return false; + } + + @Override + final public String toString() { + String ret = lpn.getLabel() + ": transition: " + getLabel() + ": \n" + + "preset: [\n"; + + for(int i = 0; i < preSet.length; i++) + ret += preSet[i]+ ","; + ret += "]\n" + + "postset: ["; + + for(int i = 0; i < postSet.length; i++) + ret += postSet[i]+ ","; + ret += "]\n"; + + return ret; + } + + public LPNTran copy(HashMap variables){ + return new LPNTran(this.label, this.index, this.preSet, this.postSet, this.enablingGuard.copy(variables), + this.assignments.copy(variables), this.delayLB, this.delayUB, this.local); + } + + + public void setLabel(String lbl) { + this.label = lbl; + } + + public String getLabel() { + return this.label; + } + + public String getFullLabel() { + return this.lpn.getLabel() + ":" + this.label; + } + + /** + * @return LPN transition's preset. + */ + public int[] getPreSet() { + return this.preSet; + } + + /** + * @param preSet the PreSet to set + */ + public void setPreSet(Collection PreSet) { + this.preSet = toArray(PreSet); + } + + /** + * @return the PostSet + */ + public HashSet getPostSet() { + HashSet ret = new HashSet(); + for(int i : this.postSet) + ret.add(i); + return ret; + } + +// /** +// * @param postSet the PostSet to set +// */ +// public void setPostSet(Collection PostSet) { +// this.postSet = toArray(PostSet); +// } + + /** + * @return the EnablingGuard + */ + public Expression getEnablingGuard() { + return enablingGuard; + } + + /** + * @param enablingGuard the EnablingGuard to set + */ + public void setEnablingGuard(Expression EnablingGuard) { + this.enablingGuard = EnablingGuard; + } + + /** + * @param assignments the Assignments to set + */ + public void setAssignments(VarExprList Assignments) { + this.assignments = Assignments; + } + + /** + * @return the DelayLB + */ + public int getDelayLB() { + return delayLB; + } + + /** + * @param DelayLB the DelayLB to set + */ + public void setDelayLB(int DelayLB) { + this.delayLB = DelayLB; + } + + /** + * @return the DelayUB + */ + public int getDelayUB() { + return delayUB; + } + + /** + * @param DelayUB the DelayUB to set + */ + public void setDelayUB(int DelayUB) { + this.delayUB = DelayUB; + } + + public String digest() { + String s = "+T." + getLabel(); + return s; + } + + /** + * Fire a transition on a state array, find new local states, and return the new state array formed by the new local states. + * @param curLpnArray + * @param curStateArray + * @param curLpnIndex + * @return + */ + public State[] fire(final StateGraph[] curSgArray, final int[] curStateIdxArray) { + State[] stateArray = new State[curSgArray.length]; + for(int i = 0; i < curSgArray.length; i++) + stateArray[i] = curSgArray[i].getState(curStateIdxArray[i]); + + return this.fire(curSgArray, stateArray); + } + + + public State[] fire(final StateGraph[] curSgArray, final State[] curStateArray) { + int thisLpnIndex = this.getLpn().getIndex(); + State[] nextStateArray = curStateArray.clone(); + + State curState = curStateArray[thisLpnIndex]; + State nextState = this.fire(curSgArray[thisLpnIndex], curState); + + int[] nextVector = nextState.getVariableVector(); + int[] curVector = curState.getVariableVector(); + + for(Expression e : assertions){ + if(e.evaluate(nextVector) == 0){ + System.err.println("Assertion " + e.toString() + " failed in LPN transition " + this.lpn.getLabel() + ":" + this.label); + System.exit(1); + } + } + + if(this.local()==true) { + nextStateArray[thisLpnIndex] = curSgArray[thisLpnIndex].addState(nextState); + return nextStateArray; + } + + HashMap vvSet = new HashMap(); + for (VarExpr s : this.getAssignments()) { + int newValue = nextVector[s.getVar().getIndex(curVector)]; + vvSet.put(s.getVar().getName(), newValue); + } + + + // Update other local states with the new values generated for the shared variables. + nextStateArray[this.lpn.getIndex()] = nextState; +// for(LPN curLpn : this.dstLpnList) { +// int curIdx = curLpn.getIndex(); + // (temp) Hack here. Probably LPNTran.java will go away. + // State newState = null; //curSgArray[curIdx].getNextState(curStateArray[curIdx], this); +// if(newState != null) { + //nextStateArray[curIdx] = newState; +// } else { + // (done) may not need to be updated, but could change to use our var index map + /* + State newOther = curStateArray[curIdx].update(vvSet, curSgArray[curIdx].getLpn().getVarIndexMap()); + if (newOther == null) + nextStateArray[curIdx] = curStateArray[curIdx]; + else { + State cachedOther = curSgArray[curIdx].addState(newOther); + //nextStateArray[curIdx] = newOther; + nextStateArray[curIdx] = cachedOther; + curSgArray[curIdx].addStateTran(curStateArray[curIdx], this, cachedOther); + } + */ + // } + // } + + return nextStateArray; + } + + // (done) Moved fire to StateGraph + public State fire(final StateGraph thisSg, final State curState) { + // Search for and return cached next state first. +// if(this.nextStateMap.containsKey(curState) == true) +// return (State)this.nextStateMap.get(curState); + // (temp) Hack here. Probably LPNTran.java will go away. + //State nextState = null; // thisSg.getNextState(curState, this); + //if(nextState != null) + // return nextState; + + // If no cached next state exists, do regular firing. + // Marking update + int[] curOldMarking = curState.getMarking(); + int[] curNewMarking = null; + if(preSet.length==0 && postSet.length==0) + curNewMarking = curOldMarking; + else { + curNewMarking = new int[curOldMarking.length - preSet.length + postSet.length]; + int index = 0; + for (int i : curOldMarking) { + boolean existed = false; + for (int prep : preSet) { + if (i == prep) { + existed = true; + break; + } + } + if (existed == false) { + curNewMarking[index] = i; + index++; + } + } + for (int postp : postSet) { + curNewMarking[index] = postp; + index++; + } + } + + // State vector update + int[] newVectorArray = curState.getVariableVector().clone(); + int[] curVector = curState.getVariableVector(); + + for (VarExpr s : getAssignments()) { + int newValue = s.getExpr().evaluate(curVector); + newVectorArray[s.getVar().getIndex(curVector)] = newValue; + } + + State newState = null; //= thisSg.addState(new State(this.lpn, curNewMarking, newVectorArray)); + + /* + int[] newVector = newState.getVariableVector(); + for(Expression e : assertions){ + if(e.evaluate(newVector) == 0){ + System.err.println("Assertion " + e.toString() + " failed in LPN transition " + this.lpn.getLabel() + ":" + this.label); + System.exit(1); + } + } + */ + // (temp) Hack here. Probably LPNTran.java will go away. + //thisSg.addStateTran(curState, this, newState); + return newState; + } + + + public List getDstLpnList(){ + return this.dstLpnList; + } + + public void addDstLpn(PlatuLPN lpn){ + this.dstLpnList.add(lpn); + } + + // Moved to StateGraph.java + public State constrFire(final State curState) { + // Marking update + int[] curOldMarking = curState.getMarking(); + int[] curNewMarking = null; + if(this.preSet.length==0 && this.postSet.length==0){ + curNewMarking = curOldMarking; + } + else { + curNewMarking = new int[curOldMarking.length - this.preSet.length + this.postSet.length]; + int index = 0; + for (int i : curOldMarking) { + boolean existed = false; + for (int prep : this.preSet) { + if (i == prep) { + existed = true; + break; + } + else if(prep > i){ + break; + } + } + + if (existed == false) { + curNewMarking[index] = i; + index++; + } + } + + for (int postp : postSet) { + curNewMarking[index] = postp; + index++; + } + } + + // State vector update + int[] oldVector = curState.getVariableVector(); + int size = oldVector.length; + int[] newVectorArray = new int[size]; + System.arraycopy(oldVector, 0, newVectorArray, 0, size); + + int[] curVector = curState.getVariableVector(); + for (VarExpr s : getAssignments()) { + int newValue = s.getExpr().evaluate(curVector); + newVectorArray[s.getVar().getIndex(curVector)] = newValue; + } + + //(temp) Hack here. Probably LPNTran.java will go away. + State newState = null; //new State(this.lpn, curNewMarking, newVectorArray); + + //int[] newVector = newState.getVariableVector(); + /* + for(Expression e : assertions){ + if(e.evaluate(newVector) == 0){ + System.err.println("Assertion " + e.toString() + " failed in LPN transition " + this.lpn.getLabel() + ":" + this.label); + System.exit(1); + } + } + */ + return newState; + } + + /** + * CHeck if enabling of 'other' depends on 'this'. + * @param other + * @return boolean + */ + public boolean dependent(LPNTran other) { + // Check if 'this' and 'other' have common places in their presets + // Check if the preset of 'other' includes places in the postset of 'this'. + // Check if the Boolean guard of 'other' depends on the variables defined by 'this'. + // If one of the three checks is true, return true; otherwise, return false. + HashSet thisVarSet = new HashSet(); + for (VarExpr assgn : this.assignments) { + thisVarSet.add(assgn.getVar().getName()); + } + + //set of variables that the Boolean guard of 'other' depends on. + for (VarNode otherVar : other.getEnablingGuard().getVariables()) { + //System.out.println(otherVar); + if (thisVarSet.contains(otherVar.getName())) { + return true; + } + } + + // if this and other transitions are in different LPNs, they are independent. + if(this.lpn.getLabel() != other.lpn.getLabel()) + return false; + + for (int i : other.preSet) { + for (int j : this.preSet) { + if (i == j) { + return true; + } + } + for (int j : this.postSet) { + if (i == j) { + return true; + } + } + } + + + + return false; + } + + /** + * @return LPN object containing this LPN transition. + */ + public PlatuLPN getLpn() { + return lpn; + } + + /** + * @param lpn - Associated LPN containing this LPN transition. + */ + public void setLpn(PlatuLPN lpn) { + this.lpn = lpn; + } + +// static public void printUsageStats() { +// System.out.printf("%-20s %11s\n", "LPNTran", counts[0]); +//// System.out.printf("\t%-20s %11s\n", "clone", counts[1]); +// System.out.printf("\t%-20s %11s\n", "getEnabledLpnTrans", counts[2]); +//// System.out.printf("\t%-20s %11s\n", "getMarkedLpnTrans", counts[3]); +//// System. out.printf("\t%-20s %11s\n", "equals", counts[4]); +// System.out.printf("\t%-20s %11s\n", "isEnabled", counts[5]); +// System.out.printf("\t%-20s %11s\n", "isTimeEnabled", counts[6]); +//// System. out.printf("\t%-20s %11s\n", "isMarked", counts[7]); +// System.out.printf("\t%-20s %11s\n", "fire", counts[8]); +//// System. out.printf("\t%-20s %11s\n", "sharePreSet", counts[9]); +// System.out.printf("\t%-20s %11s\n", "disablingError", counts[10]); +//// System. out.println("getEnTrans: "+stats.toString()); +// } + + public void print() { + System.out.println(lpn.getLabel() + ": transition: " + getLabel() + ": "); + + System.out.print("preset: ["); + for(int i = 0; i < preSet.length; i++) + System.out.print(preSet[i]+ ","); + System.out.println("]"); + + System.out.print("postset: ["); + for(int i = 0; i < postSet.length; i++) + System.out.print(postSet[i]+ ","); + System.out.println("]"); + + //System.out.print("\t Guard: "); + //enablingGuard.print(); + } + + /** + * @return the assignments + */ + public VarExprList getAssignments() { + return assignments; + } + + + /** + * Inserts a Boolean expression into LPNTran's assertion list. + * @param booleanExpr - Boolean expression + * @return void + */ + public void addAssertion(Expression booleanExpr){ + assertions.add(booleanExpr); + } + + /** + * Inserts a collection of Boolean expressions into LPNTran's assertion list. + * @param booleanExprs - collection of Boolean expressions + * @return void + */ + public void addAllAssertions(Collection booleanExprs){ + assertions.addAll(booleanExprs); + } + + /** + * Returns true if LPNTran only modifies non-output variables. + * @return Boolean + */ + public boolean local(){ + return this.local; + } + + public void setLocalFlag(boolean flag){ + this.local = flag; + } + + public String getAssignmentString(){ + String ret=""; + for(VarExpr ve:getAssignments()){ + + ret+=ve.toString()+"; "; + } + return ret; + } + + public String getLabelString(){ + return lpn.getLabel() + ":" + getLabel(); + } + + public void setIndex(int idx) { + this.index = idx; + } + + public int getIndex() { + return this.index; + } + + /* + * Needed in Moore's code. Should be removed later. + */ + public static int getID() { + return 0; + } + + public void setSticky(){ + this.stickyFlag = true; + } + + public boolean sticky(){ + return this.stickyFlag; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/LPNTranRelation.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/LPNTranRelation.java new file mode 100644 index 000000000..9edf6e19c --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/LPNTranRelation.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.platuLpn; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +import java.util.Set; + +/** + * The LPNTranRelation class stores information about LPN transitions such as dependence, + * interleaving, and independence. + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ + public class LPNTranRelation { + private List designUnitSet = null; + private Map> transitiveDependence = new HashMap>(); // type 1 transitive + private Map> interleavingDependence = new HashMap>(); // type 2 interleaving +// public Map> case2 = new HashMap>(); + + public LPNTranRelation(List designUnitSet){ + this.designUnitSet = designUnitSet; + } + + /** + * Finds pairs of transitions which are dependent locally and between modules. Identifies two types of dependencies: + * 1) transitive + * 2) interleaving + * This function assumes findSgCompositional() has been called. + * Type 1 pairs are stored in Map transitiveDependence, and type 2 pairs are stored in Map interleavingDependence. + */ + public void findCompositionalDependencies(){ + for(StateGraph sg : this.designUnitSet){ + //for(State currentState : sg.reachable()){ + for(State currentState : sg.getStateSet()) { + Set> stateTranSet = sg.getOutgoingTrans(currentState); + if(stateTranSet == null) continue; + + for(Entry stateTran: stateTranSet){ + State startState = currentState; + State endState = stateTran.getValue(); + Transition lpnTran = stateTran.getKey(); + + //TODO: (original) only get enabled trans from lpn or input transitions also? + LpnTranList currentEnabledTransitions = sg.getEnabled(startState); + LpnTranList nextEnabledTransitions = sg.getEnabled(endState); + + // disabled trans + LpnTranList current_minus_next = currentEnabledTransitions;//currentEnabledTransitions.clone(); + current_minus_next.removeAll(nextEnabledTransitions); + current_minus_next.remove(lpnTran); + + // type 2 + for(Transition disabledTran: current_minus_next){ + // t1 -> t2 + if(interleavingDependence.containsKey(lpnTran)){ + interleavingDependence.get(lpnTran).add(disabledTran); + } + else{ + Set tranSet = new HashSet(); + tranSet.add(disabledTran); + interleavingDependence.put(lpnTran, tranSet); + } + + if(interleavingDependence.containsKey(disabledTran)){ + interleavingDependence.get(disabledTran).add(lpnTran); + } + else{ + Set tranSet = new HashSet(); + tranSet.add(lpnTran); + interleavingDependence.put(disabledTran, tranSet); + } + } + + // enabled trans + LpnTranList next_minus_current = nextEnabledTransitions; + next_minus_current.removeAll(currentEnabledTransitions); + + // type 1 + for(Transition enabledTran: next_minus_current){ + // t1 -> t2 + if(transitiveDependence.containsKey(lpnTran)){ + transitiveDependence.get(lpnTran).add(enabledTran); + } + else{ + Set tranSet = new HashSet(); + tranSet.add(enabledTran); + transitiveDependence.put(lpnTran, tranSet); + } + } + + LpnTranList remainEnabled = currentEnabledTransitions; + remainEnabled.removeAll(current_minus_next); + for(Transition remainTran : remainEnabled){ + State s1 = sg.getNextState(currentState, remainTran); + if(s1 == null) continue; + + LpnTranList en = sg.getEnabled(s1); + if(!en.contains(lpnTran)) continue; + + State s3 = sg.getNextState(s1, lpnTran); + State s2 = sg.getNextState(endState, remainTran); + if(s2 == null) continue; + if(s3 == null) continue; + + if(s2 != s3){ + if(interleavingDependence.containsKey(lpnTran)){ + interleavingDependence.get(lpnTran).add(remainTran); + } + else{ + Set tranSet = new HashSet(); + tranSet.add(remainTran); + interleavingDependence.put(lpnTran, tranSet); + } + + if(interleavingDependence.containsKey(remainTran)){ + interleavingDependence.get(remainTran).add(lpnTran); + } + else{ + Set tranSet = new HashSet(); + tranSet.add(lpnTran); + interleavingDependence.put(remainTran, tranSet); + } + + // if(case2.containsKey(lpnTran)){ + // case2.get(lpnTran).add(remainTran); + // } + // else{ + // Set tranSet = new HashSet(); + // tranSet.add(remainTran); + // case2.put(lpnTran, tranSet); + // } + } + } + } + } + } + } + + /** + * Returns entry set of Map transitiveDependence, where the key value is an LPNTran + * and the value is a list of LPNTran which have transitive dependence. + * @return Map transitiveDependence entry set + */ + public Set>> getDependentTrans(){ + return this.transitiveDependence.entrySet(); + } + + /** + * Returns entry set of Map interleavingDependence, where the key value is an LPNTran + * and the value is a list of LPNTran which have interleaving dependence. + * @return Map interleavingDependence entry set + */ + public Set>> getInterleavingTrans(){ + return this.interleavingDependence.entrySet(); + } + + public void printCompositionalDependencies() { + System.out.println("------- Compositional Dependencies -----------"); + if (interleavingDependence.isEmpty()) { + System.out.println("empty interleavingDependence."); + } + else { + for (Transition tran : interleavingDependence.keySet()) { + System.out.println("interleaving dependency for tran = " + tran.getFullLabel()); + for (Transition depTran : interleavingDependence.get(tran)) { + System.out.println("\t" + depTran.getFullLabel()); + } + } + } + if (transitiveDependence.isEmpty()) { + System.out.println("empty transitiveDependence."); + for (Transition tran : transitiveDependence.keySet()) { + System.out.println("transitive dependency for tran = " + tran.getFullLabel()); + for (Transition depTran : transitiveDependence.get(tran)) { + System.out.println("\t" + depTran.getFullLabel()); + } + } + } + + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/LpnTranList.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/LpnTranList.java new file mode 100644 index 000000000..264f7d269 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/LpnTranList.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.platuLpn; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.platuLpn.PlatuLPN; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +final public class LpnTranList extends LinkedList { + + private static final long serialVersionUID = 1L; + private LPN lpn; + + public LpnTranList() { + super(); + } + + public LpnTranList(Collection lpnt) { + super(lpnt); + } + + public LpnTranList(final int i) { + } + + public Transition get(Transition lpnt) { + for (Transition t: this) { + if (lpnt.getLabel() == t.getLabel()) { + return t; + } + } + return null; + } + + /** + * @return the lpn + */ + public LPN getLpn() { + return lpn; + } + + /** + * @param lpn2 the lpn to set + */ + public void setLPN(LPN lpn2) { + this.lpn = lpn2; + for (Transition t : this) { + t.setLpn(lpn2); + } + } + + @Override + public String toString() { + String ret = ""; + Iterator it = this.iterator(); + while (it.hasNext()) { + ret += it.next().getLabel(); + if (it.hasNext()) { + ret += ", "; + } + } + return "[" + ret + "]"; + } + + @Override + public LpnTranList clone() { + return new LpnTranList(this); + } + + // TODO: (check) copy has been rewritten. + /* + public LpnTranList copy(HashMap variables){ + LpnTranList copy = new LpnTranList(); + for(LPNTran lpnTran : this){ + copy.add(lpnTran.copy(variables)); + } + + return copy; + } + */ + public LpnTranList copy() { + LpnTranList copy = new LpnTranList(); + for (Transition lpnTran: this) { + copy.add(lpnTran); + } + return copy; + } + + public void setLPN(PlatuLPN lpn2) { + // Hack here. This is used to get rid of errors in PlatuGrammearParser. + + } + + public void add(LPNTran transition4) { + // Hack here. This is used to get rid of errors in PlatuGrammearParser. + + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/PlatuLPN.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/PlatuLPN.java new file mode 100644 index 000000000..96bee2103 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/PlatuLPN.java @@ -0,0 +1,950 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.platuLpn; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map.Entry; + +import edu.utah.ece.async.lema.verification.platu.expression.ArrayNode; +import edu.utah.ece.async.lema.verification.platu.expression.VarNode; +import edu.utah.ece.async.lema.verification.platu.project.Project; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class PlatuLPN { + public static int nextID=1; + static private List emptyStringList = new ArrayList(); + static private List emptyArrayList = new ArrayList(); + static private String[] emptyStringArray = new String[0]; + static private int[] emptyIntArray = new int[0]; + + public int ID=nextID++; + + protected Project prj; // Pointer to the top-level ProjDef.. + + protected String label; // Label of this LPN. + + protected int index; + + /* Variables read by this LPN but defined by other LPNs*/ + protected VarSet inputs; + + /* Variables defined this LPN. Shared variables can be defined by this and other LPNs */ + protected VarSet outputs; + + /* Variables defined and read only by this LPN*/ + protected VarSet internals; + + protected HashMap varNodeMap; + + protected LpnTranList transitions; + + //protected Object initState; + private int[] initMark; + private HashMap initVector; + + protected DualHashMap varIndexMap = new DualHashMap(); + + /* Transitions that modify the input variables in 'inputs'*/ + protected List inputTranSet = new ArrayList(); + + /* Transitions that modify the output variables in 'outputs'*/ + protected List outputTranSet = new ArrayList(); + + protected StateGraph stateGraph; + protected String[] interfaceVariables = emptyStringArray; + protected int[] interfaceIndices = emptyIntArray; + protected List thisIndexList = emptyArrayList; + protected List otherIndexList = emptyArrayList; + protected List argumentList = emptyStringList; + + + public StateGraph getStateGraph(){ + return this.stateGraph; + } + + @Override + public String toString() { + String ret = ""; + ret += prj + "\n"; + ret += label + "\n"; + ret += getInputs() + "\n"; + ret += getOutputs() + "\n"; + ret += getInternals() + "\n"; + ret += getTransitions() + "\n"; + ret += this.varIndexMap + "\n"; + ret += this.initVector + "\n"; + ret += this.varNodeMap + "\n"; + return ret; + } + + public PlatuLPN(Project prj, String label, VarSet inputs, VarSet outputs, + VarSet internals, LpnTranList transitions) { + this.prj = prj; + this.label = label; + this.inputs = inputs; + this.outputs = outputs; + this.internals = internals; + this.transitions = transitions; + if (prj == null || label == null || inputs == null ||// + outputs == null || internals == null + || transitions == null) { + new NullPointerException().printStackTrace(); + } + + // Adjust the visibility of lpn transitions. + // TODO: (temp) Hack here, but no problem as LPN.java will go away. + // TODO: cut below because transitionsTemp is null + /* + ArrayList transitionsTemp = null; + for (LPNTran curTran : transitionsTemp) { //transitions) { + curTran.initialize(this, outputs); + } + */ + // TODO: (temp) Hack here, but no problem as LPN.java will go away. + this.stateGraph = null; //new StateGraph(this); + } + + public PlatuLPN(Project prj, String label, VarSet inputs, VarSet outputs, + VarSet internals, HashMap varNodeMap, LpnTranList transitions, + HashMap initialVector, int[] initialMarkings) { + this.prj = prj; + this.label = label; + this.inputs = inputs; + this.outputs = outputs; + this.internals = internals; + this.transitions = transitions; + this.initVector = initialVector; + this.initMark = initialMarkings; + this.varNodeMap = varNodeMap; + + if (prj == null || label == null || inputs == null ||// + outputs == null || internals == null + || transitions == null) { + new NullPointerException().printStackTrace(); + } + + // Adjust the visibility of lpn transitions. + // TODO: (temp) Hack here, but no problem as LPN.java will go away. + // (temp) Hack here, but no problem as LPN.java will go away. + // TODO: cut below because transitionsTemp is null + /* + ArrayList transitionsTemp = null; + for (LPNTran curTran : transitionsTemp) { + curTran.initialize(this, outputs); + } + */ + // TODO: (temp) Hack here, but no problem as LPN.java will go away. + this.stateGraph = null; // new StateGraph(this); + } + + @Override + public PlatuLPN clone() { + // copy varNodeMap + HashMap varNodeMap = new HashMap(); + List arrayNodes = new LinkedList(); + + for(Entry e : this.varNodeMap.entrySet()){ + VarNode var = e.getValue(); + if(ArrayNode.class.isAssignableFrom(var.getClass())){ + arrayNodes.add((ArrayNode)var); + } + else{ + varNodeMap.put(e.getKey(), var.clone()); + } + } + + for(ArrayNode array : arrayNodes){ + ArrayNode copyNode = (ArrayNode) array.copy(varNodeMap); + varNodeMap.put(copyNode.getName(), copyNode); + } + + // copy transitions + // TODO: (temp) Hack here, but no problem as LPN.java will go away. + LpnTranList transitions = null; //this.transitions.copy(varNodeMap); + + // copy varIndexMap + DualHashMap varIndexMap = this.varIndexMap.clone(); + + // copy initVector + HashMap initVector = new HashMap(this.initVector); + + // copy of zone + PlatuLPN newLPN = new PlatuLPN(this.prj, this.label, this.inputs.clone(), this.outputs.clone(), + this.internals.clone(), varNodeMap, transitions, initVector, this.initMark); + + // TODO: have to cut below because transitions is null + // transitions.setLPN(newLPN); + newLPN.setVarIndexMap(varIndexMap); + newLPN.argumentList = this.argumentList; + + return newLPN; + } + + public void setGlobals(List designUnitSet){ + List removeList = new ArrayList(); + List addList = new ArrayList(); + for(String output : this.outputs){ + VarNode var = varNodeMap.get(output); + if(var.getType() == VarType.GLOBAL){ + if(ArrayNode.class.isAssignableFrom(var.getClass())){ + removeList.add(output); + + for(VarNode element : ((ArrayNode)var).getVariableList()){ + addList.add(element.getName()); + } + // TODO: (temp) Hack here, but no problem as LPN.java will go away. + // TODO: cut below because transitionsTemp is null + /* + ArrayList transitionsTemp = null; + for(LPNTran lpnTran : transitionsTemp) {//this.transitions){ + for(VarNode assignedVar : lpnTran.getAssignedVar()){ + if(ArrayElement.class.isAssignableFrom(assignedVar.getClass()) && ((ArrayElement)assignedVar).getArray() == var){ + this.addOutputTran(lpnTran); + lpnTran.setLocalFlag(false); + for(StateGraph sg : designUnitSet){ + // TODO: (temp) broken but okay depracting this class + *//* + LPN dstLpn = sg.getLpn(); + if(dstLpn == this) continue; + + dstLpn.addInputTran(lpnTran); + lpnTran.addDstLpn(dstLpn); + *//* + } + } + } + } + */ + } + else{ + // TODO: (temp) Hack here, but no problem as LPN.java will go away. + // TODO: cut below because transitionsTemp is null + /* + ArrayList transitionsTemp = null; + for(LPNTran lpnTran : transitionsTemp) {//this.transitions){ + if(lpnTran.getAssignedVar().contains(var)){ + System.out.println(output); + this.addOutputTran(lpnTran); + lpnTran.setLocalFlag(false); + + for(StateGraph sg : designUnitSet){ + // TODO: (temp) broken but okay depracting this class + *//* + LPN dstLpn = sg.getLpn(); + if(dstLpn == this) continue; + + dstLpn.addInputTran(lpnTran); + lpnTran.addDstLpn(dstLpn); + *//* + } + } + } + */ + } + } + } + + this.outputs.removeAll(removeList); + this.outputs.addAll(addList); + } + + public PlatuLPN instantiate(String label){ + PlatuLPN newLpn = this.clone(); + int[] currentVector = null;//newLpn.getInitState().getVector(); + newLpn.setLabel(label); +// StateGraph sg = (StateGraph) newLpn; +// sg.setLabel(label); + + HashMap varNodeMap = newLpn.getVarNodeMap(); + HashMap initialVector = newLpn.getInitVector(); + DualHashMap varIndexMap = newLpn.getVarIndexMap(); + + List outputs = new LinkedList(); + VarSet outputSet = newLpn.getOutputs(); + for(String output : outputSet){ + VarNode var = varNodeMap.get(output); + if(var.getType() == VarType.GLOBAL){ + outputs.add(var.getName()); + continue; + } + + String newName = label + "." + output; + outputs.add(newName); + + varNodeMap.remove(output); + var.setName(newName); + varNodeMap.put(newName, var); + + if(ArrayNode.class.isAssignableFrom(var.getClass())){ + List varList = ((ArrayNode)var).getVariableList(); + int size = varList.size(); + for(int i = 0; i < size; i++){ + VarNode elementNode = varList.get(i); + int val = initialVector.get(elementNode.getName()); + + varNodeMap.remove(elementNode.getName()); + varIndexMap.delete(elementNode.getName()); + initialVector.remove(elementNode.getName()); + + String elementName = label + "." + elementNode.getName(); + elementNode.setName(elementName); + + varNodeMap.put(elementName, elementNode); + initialVector.put(elementName, val); + varIndexMap.insert(elementName, elementNode.getIndex(currentVector)); + } + } + else{ + int val = initialVector.get(output); + initialVector.remove(output); + initialVector.put(newName, val); + + varIndexMap.delete(output); + varIndexMap.insert(newName, var.getIndex(currentVector)); + } + } + + outputSet.clear(); + outputSet.addAll(outputs); + + List internals = new LinkedList(); + VarSet internalSet = newLpn.getInternals(); + for(String internal : internalSet){ + String newName = label + "." + internal; + internals.add(newName); + + VarNode var = varNodeMap.get(internal); + varNodeMap.remove(internal); + var.setName(newName); + varNodeMap.put(newName, var); + + if(ArrayNode.class.isAssignableFrom(var.getClass())){ + List varList = ((ArrayNode)var).getVariableList(); + int size = varList.size(); + for(int i = 0; i < size; i++){ + VarNode elementNode = varList.get(i); + int val = initialVector.get(elementNode.getName()); + + varNodeMap.remove(elementNode.getName()); + varIndexMap.delete(elementNode.getName()); + initialVector.remove(elementNode.getName()); + + String elementName = label + "." + elementNode.getName(); + elementNode.setName(elementName); + + varNodeMap.put(elementName, elementNode); + initialVector.put(elementName, val); + varIndexMap.insert(elementName, elementNode.getIndex(currentVector)); + } + } + else{ + int val = initialVector.get(internal); + initialVector.remove(internal); + initialVector.put(newName, val); + + varIndexMap.delete(internal); + varIndexMap.insert(newName, var.getIndex(currentVector)); + } + } + + internalSet.clear(); + internalSet.addAll(internals); + + // varIndexMap + initialVector + return newLpn; + } + + public void connect(String outputVar, PlatuLPN dstLpn, String inputVar){ + int[] initVector = null; // this.getInitState().getVector(); + + // change outputVar to an output if not already + // move to output list + // set type + + VarNode outputVarNode = this.varNodeMap.get(outputVar); + if(outputVarNode == null){ + System.err.println("connect: " + outputVar + " does not exist in " + this.getLabel()); + return; + } + + // find associated LPNTrans + // put in outputTranList if not already + // put in dstLpn's inputTranList + // set as non local + // (temp) Hack here, but no problem as LPN.java will go away. + // TODO: cut below because transitionsTemp is null + /* + ArrayList transitionsTemp = null; + for(LPNTran lpnTran : transitionsTemp) {//this.transitions){ + if(lpnTran.getAssignedVar().contains(outputVarNode)){ + this.addOutputTran(lpnTran); + dstLpn.addInputTran(lpnTran); + lpnTran.setLocalFlag(false); + lpnTran.addDstLpn(dstLpn); + } + } + */ + // get input VarNode + // make sure it is an input + VarNode inputVarNode = dstLpn.varNodeMap.get(inputVar); + dstLpn.varNodeMap.remove(inputVar); + dstLpn.varNodeMap.put(outputVar, inputVarNode); + if(inputVarNode == null){ + System.err.println("connect: " + inputVar + " does not exist in " + dstLpn.getLabel()); + return; + } + else if(!dstLpn.getInputs().contains(inputVar)){ + System.err.println("connect: " + inputVar + " is not an input variable"); + return; + } + + // make sure types are compatible + if(ArrayNode.class.isAssignableFrom(inputVarNode.getClass())){ + if(!ArrayNode.class.isAssignableFrom(outputVarNode.getClass())){ + System.err.println("error: variable " + inputVarNode.getName() + " is an array"); + return; + } + + // make sure dimensions are the same + List inputDimensions = ((ArrayNode)inputVarNode).getDimensionList(); + List outputDimensions = ((ArrayNode)outputVarNode).getDimensionList(); + + if(inputDimensions.size() != outputDimensions.size()){ + System.err.println("error: incompatible dimensions"); + return; + } + + for(int i = 0; i < inputDimensions.size(); i++){ + if(inputDimensions.get(i) != outputDimensions.get(i)){ + System.err.println("error: incompatible dimensions"); + return; + } + } + } + else if(ArrayNode.class.isAssignableFrom(outputVarNode.getClass())){ + System.err.println("error: variable " + outputVarNode.getName() + " is an array"); + return; + } + + if(ArrayNode.class.isAssignableFrom(outputVarNode.getClass())){ + if(this.internals.contains(outputVar)){ + this.internals.remove(outputVar); + outputVarNode.setType(VarType.OUTPUT); +// this.outputs.add(outputVar); + } + else if(!outputVarNode.getType().equals(VarType.OUTPUT)){ + System.err.println("connect: " + outputVar + " is not an internal or output var in " + this.getLabel()); + return; + } + + ArrayNode inputArray = (ArrayNode) inputVarNode; + ArrayNode outputArray = (ArrayNode) outputVarNode; + + VarSet inputs = dstLpn.getInputs(); + inputs.remove(inputArray.getName()); + + inputArray.setAlias(inputArray.getName()); + inputArray.setName(outputArray.getName()); + + List inputVarList = inputArray.getVariableList(); + List outputVarList = outputArray.getVariableList(); + HashMap dstVarNodeMap = dstLpn.getVarNodeMap(); + for(int i = 0; i < inputVarList.size(); i++){ + inputVarNode = inputVarList.get(i); + inputVarNode.setType(VarType.INPUT); + dstVarNodeMap.remove(inputVarNode.getName()); + + outputVarNode = outputVarList.get(i); + outputVarNode.setType(VarType.OUTPUT); + + // TODO: (temp) Hack here, but no problem as LPN.java will go away. + // TODO: cut below because transitionsTemp is null + /* + for(LPNTran lpnTran : transitionsTemp) {//this.transitions){ + for(VarNode assignedVar : lpnTran.getAssignedVar()){ + if(ArrayElement.class.isAssignableFrom(assignedVar.getClass()) && ((ArrayElement)assignedVar).getArray() == outputArray){ + this.addOutputTran(lpnTran); + dstLpn.addInputTran(lpnTran); + lpnTran.setLocalFlag(false); + lpnTran.addDstLpn(dstLpn); + } + } + } + */ + // get output initial value + // modify dstLpn's init vector + int initialValue = this.getInitVector().get(outputVarNode.getName()); + HashMap initialVector = dstLpn.getInitVector(); + initialVector.remove(inputVarNode.getName()); + initialVector.put(outputVarNode.getName(), initialValue); + + // Change input var name + // find var in varNodeMap + // change name to output var name + // set alias - old name + // change inputs list + // change varIndexMap + +// inputs.remove(inputVar); +// inputs.add(outputVar); + DualHashMap varIndexMap = dstLpn.getVarIndexMap(); + varIndexMap.delete(inputVarNode.getName()); + varIndexMap.insert(outputVarNode.getName(), inputVarNode.getIndex(initVector)); + + inputVarNode.setAlias(inputVarNode.getName()); + inputVarNode.setName(outputVarNode.getName()); + dstVarNodeMap.put(inputVarNode.getName(), inputVarNode); + + inputs.add(inputVarNode.getName()); + this.outputs.add(outputVarNode.getName()); +// System.out.println(inputVarNode.getName() + ", " + outputVarNode.getName() + ", " + outputVar); + } + } + else{ + if(this.internals.contains(outputVar)){ + this.internals.remove(outputVar); + this.outputs.add(outputVar); + outputVarNode.setType(VarType.OUTPUT); + } + else if(!this.outputs.contains(outputVar)){ + System.err.println("connect: " + outputVar + " is not an internal or output var in " + this.getLabel()); + System.exit(1); + } + + // get output initial value + // modify dstLpn's init vector + int initialValue = this.getInitVector().get(outputVarNode.getName()); + HashMap initialVector = dstLpn.getInitVector(); + initialVector.remove(inputVar); + initialVector.put(outputVar, initialValue); + + // Change input var name + // find var in varNodeMap + // change name to output var name + // set alias - old name + // change inputs list + // change varIndexMap + + inputVarNode.setAlias(inputVarNode.getName()); + inputVarNode.setName(outputVar); + VarSet inputs = dstLpn.getInputs(); + inputs.remove(inputVar); + inputs.add(outputVar); + DualHashMap varIndexMap = dstLpn.getVarIndexMap(); + varIndexMap.delete(inputVar); + varIndexMap.insert(outputVar, inputVarNode.getIndex(initVector)); + } + } + + public HashMap getVarNodeMap(){ + return this.varNodeMap; + } + + public void insert(LPNTran tran) { + tran.setLpn(this); + this.getTransitions().add(tran); + } + +// public final VarVal insert(final VarVal prop) { +// counts[4]++; +// return prj.insert(prop); +// } + +// // Create a new LPN by composing 'this' LPN with 'other'. +// final public LPN compose(final LPN other, final String dest) { +// counts[5]++; +// if (this == null) { +// new NullPointerException().printStackTrace(); +// } +// if (other == null) { +// new NullPointerException().printStackTrace(); +// } +// if (dest == null) { +// new NullPointerException().printStackTrace(); +// } +// if (getTransitions().size() == 0) { +// new Exception("transitions.size()==0").printStackTrace(); +// } +// +// VarSet otherIn = new VarSet(other.getInputs()); +// VarSet otherOut = new VarSet(other.getOutputs()); +// VarSet otherIntr = new VarSet(other.getInternals()); +// VarSet thisIn = new VarSet(this.getInputs()); +// VarSet thisOut = new VarSet(this.getOutputs()); +// VarSet thisIntr = new VarSet(this.getInternals()); +// VarSet retIn = new VarSet(); +// VarSet retOut = new VarSet(); +// VarSet retIntr = new VarSet(); +// retIn.addAll(thisIn); +// retIn.addAll(otherIn); +// retOut.addAll(thisOut); +// retOut.addAll(otherOut); +// retIntr.addAll(thisIntr); +// retIntr.addAll(otherIntr); +// retIn.removeAll(retOut); +// retIn.removeAll(retIntr); +// +// TimedState retInitState = null;//this.getInitStateTimed().compose(other.getInitStateTimed()); +// // HashSet common = new HashSet(); +// // Iterator it = thisIn.iterator(); +// // String tmp; +// // while (it.hasNext()) { +// // tmp = it.next(); +// // if (otherIn.contains(tmp)) { +// // common.add(tmp); +// // } +// // } +// if (otherIn == null +// || otherOut == null +// || otherIntr == null +// || thisIn == null +// || thisOut == null +// || thisIntr == null +// || retIn == null +// || retOut == null +// || retIntr == null) { +// if (ENABLE_PRINT) { +// System.err.println(otherIn + "\n\t" +// + otherOut + "\n\t" +// + otherIntr + "\n\t" +// + thisIn + "\n\t" +// + thisOut + "\n\t" +// + thisIntr + "\n\t" +// + retIn + "\n\t" +// + retOut + "\n\t" +// + retIntr); +// } +// new NullPointerException().printStackTrace(); +// } +// LPN ret = new LPN(prj, dest, +// new VarSet(retIn), +// new VarSet(retOut), +// new VarSet(retIntr), +// new LPNTranSet(), +// retInitState); +// ret.getTransitions().addAll(this.getTransitions()); +// ret.getTransitions().addAll(other.getTransitions()); +// return ret; +// } + + static String blankString(int len) { + String ret = ""; + for (int i = 0; i < len; i++) { + ret += " "; + } + return ret; + } + + public final String description() { + String description = String.format("%-10s%-25s%-25s%-25s", + getLabel() + ": ", " Inputs: " + (getInputs().size()), + " Outputs: " + (getOutputs().size()), " Internals: " + (getInternals().size())); + return description; + } + + public final String description2() { + String description = String.format("%-10s%-25s%-25s%-25s", + getLabel() + ": ", " Inputs: " + (getInputs()), + " Outputs: " + (getOutputs()), " Internals: " + (getInternals())); + return description; + } + // end of function findSG(...) + + /** + @return the instance_label + */ + public String getLabel() { + return label; + } + + public void setIndex(int newIdx) { + this.index = newIdx; + } + + public int getIndex() { + return this.index; + } + + public Project getProj() { + return this.prj; + } + + /** + @return the Inputs + */ + public VarSet getInputs() { + return inputs; + } + + /** + @return the Outputs + */ + public VarSet getOutputs() { + return outputs; + } + + /** + @return the Internals + */ + public VarSet getInternals() { + return internals; + } + + /** + @return the transitions + */ + public LpnTranList getTransitions() { + return transitions; + } + + public static LpnTranList getOutputTrans() { + LpnTranList outputTranSet = new LpnTranList(); + // TODO: (temp) Hack here, but no problem as LPN.java will go away. + // TODO: cut below because transitionsTemp is null + /* + ArrayList transitionsTemp = null; + for (LPNTran curTran : transitionsTemp) {// this.transitions) { + HashSet assignedVars = curTran.getAssignedVar(); + for (VarNode var : assignedVars) { + if (this.outputs.contains(var.getName()) == true) { + outputTranSet.add(curTran); + break; + } + } + } + */ + return outputTranSet; + } + + public void addInputTran(LPNTran inputTran){ + this.inputTranSet.add(inputTran); + } + + public void addOutputTran(LPNTran outputTran){ + this.outputTranSet.add(outputTran); + } + + public void addAllInputTrans(Collection inputTrans){ + this.inputTranSet.addAll(inputTrans); + } + + public void addAllOutputTrans(Collection outputTrans){ + this.outputTranSet.addAll(outputTrans); + } + + /** + @return the InitState + */ + /* + public State getInitState() { + // create initial vector + int size = this.varIndexMap.size(); + int[] initialVector = new int[size]; + for(int i = 0; i < size; i++) { + String var = this.varIndexMap.getKey(i); + int val = this.initVector.get(var); + initialVector[i] = val; + } + + return new State(this, this.initMark, initialVector); + } + */ + public HashMap getInitVector(){ + return this.initVector; + } + + /** + * @param label the label to set + */ + public void setLabel(String label) { + this.label = label; + } + + /** + * @param inputs the inputs to set + */ + public void setInputs(VarSet inputs) { + this.inputs = inputs; + } + + /** + * @param outputs the outputs to set + */ + public void setOutputs(VarSet outputs) { + this.outputs = outputs; + } + + /** + * @param internals the internals to set + */ + public void setInternals(VarSet internals) { + this.internals = internals; + } + + /** + * @param transitions the transitions to set + */ + public void setTransitions(LpnTranList transitions) { + this.transitions = transitions; + } + + public void setVarIndexMap(DualHashMap m) { + this.varIndexMap = m; + } + + public DualHashMap getVarIndexMap() { + return this.varIndexMap; + } + + public void genIndexLists(int[] thisIndexList, int[] otherIndexList, PlatuLPN otherLpn){ + int arrayIndex = 0; + DualHashMap otherVarIndexMap = otherLpn.getVarIndexMap(); + String[] interfaceVars = otherLpn.getInterfaceVariables(); + + for(int i = 0; i < interfaceVars.length; i++){ + String var = interfaceVars[i]; + Integer thisIndex = this.varIndexMap.getValue(var); + if(thisIndex != null){ + thisIndexList[arrayIndex] = thisIndex; + otherIndexList[arrayIndex] = otherVarIndexMap.getValue(var); + + arrayIndex++; + } + } + } + + public List getInputTranSet(){ + return this.inputTranSet; + } + + public List getOutputTranSet(){ + return this.outputTranSet; + } + + public int[] getThisIndexArray(int i){ + return this.thisIndexList.get(i); + } + + public int[] getOtherIndexArray(int i){ + return this.otherIndexList.get(i); + } + + public void setArgumentList(List argList){ + this.argumentList = argList; + } + + public List getArgumentList(){ + return this.argumentList; + } + + public void setThisIndexList(List indexList){ + this.thisIndexList = indexList; + } + + public void setOtherIndexList(List indexList){ + this.otherIndexList = indexList; + } + + public List getThisIndexList(){ + return this.thisIndexList; + } + + public List getOtherIndexList(){ + return this.otherIndexList; + } + + public String[] getInterfaceVariables(){ + if(interfaceVariables.length == 0){ + int size = inputs.size() + outputs.size(); + interfaceVariables = new String[size]; + HashSet interfaceSet = new HashSet(); + int i = 0; + for(String input : inputs){ + interfaceVariables[i++] = input; + interfaceSet.add(input); + } + + for(String output : outputs){ + if(interfaceSet.contains(output)) continue; + interfaceVariables[i++] = output; + } + } + + return interfaceVariables; + } + + public int[] getInterfaceIndices(){ + if(interfaceIndices.length == 0){ + int size = inputs.size() + outputs.size(); + interfaceIndices = new int[size]; + + int i = 0; + for(String input : inputs){ + interfaceIndices[i++] = varIndexMap.getValue(input); + } + + for(String output : outputs){ + interfaceIndices[i++] = varIndexMap.getValue(output); + } + } + + return interfaceIndices; + } + + public boolean isInput(LPNTran lpnTr) { + return this.inputTranSet.contains(lpnTr); + } + + public boolean isOutput(LPNTran lpnTr) { + return this.outputTranSet.contains(lpnTr); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((label == null) ? 0 : label.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PlatuLPN other = (PlatuLPN) obj; + if (label == null) { + if (other.label != null) + return false; + } else if (!label.equals(other.label)) + return false; + return true; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarExpr.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarExpr.java new file mode 100644 index 000000000..5012776c9 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarExpr.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.platuLpn; + +import java.util.HashMap; + +import edu.utah.ece.async.lema.verification.platu.expression.Expression; +import edu.utah.ece.async.lema.verification.platu.expression.VarNode; + +/** + * Assignment data structure. + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class VarExpr { + private VarNode var; + private Expression expr; + + public VarExpr(VarNode var, Expression expr){ + this.var = var; + this.expr = expr; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof VarExpr) { + VarExpr other = (VarExpr) obj; + return getVar() == other.getVar() && expr.toString().compareTo(other.expr.toString()) == 0; + } + + return false; + } + + public VarExpr copy(HashMap variables){ + return new VarExpr((VarNode) this.var.copy(variables), this.expr.copy(variables)); + } + + /** + * @return The variable assigned. + */ + public VarNode getVar() { + return var; + } + + /** + * @return The assignment expression. + */ + public Expression getExpr() { + return expr; + } + + /** + * @param expr The assignment expression. + */ + public void setExpr(Expression expr) { + this.expr = expr; + } + + /** + * @param var The assigned variable. + */ + public void setVar(VarNode var) { + this.var = var; + } + + @Override + public int hashCode() { + return super.hashCode(); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarExprList.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarExprList.java new file mode 100644 index 000000000..acf0ff261 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarExprList.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package edu.utah.ece.async.lema.verification.platu.platuLpn; + +import java.util.*; + +import edu.utah.ece.async.lema.verification.platu.expression.Expression; +import edu.utah.ece.async.lema.verification.platu.expression.VarNode; + +/** + * @author ldtwo + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class VarExprList extends ArrayList { + +// public VarExprList(String[] list,DualHashMap dhm) { +// super(); +// for (String s : list) { +// if (s.length() > 0) { +// add(new VarExpr(s,dhm)); +// } +// } +// } + +// public VarExprList(VarExprList l,DualHashMap dhm) { +// +// for(VarExpr ve:l){ +// add(new VarExpr(ve.getVar(), ve.getExpr().getExpression(),dhm)); +// } +// } + + /** + * + */ + private static final long serialVersionUID = 1L; + + public VarExprList() { + super(); + } + + @Override + public String toString() { + String ret = ""; + int x = 0; + try { + for (; x < this.size() - 1; x++) { + ret += this.get(x).getVar() + " = " + this.get(x).getExpr() + ";"; + }//x=this.size()-1 ; + if (size() > 0) { + ret += this.get(x).getVar() + " = " + this.get(x).getExpr(); + } + } catch (Exception e) { + System.err.print("ret=" + ret + "\tx=" + x + "\tsize=" + size() + "\tget(x)="); + try { + System.err.println(get(x)); + } catch (Exception e2) { + try { + Thread.sleep(300); + } catch (InterruptedException ex) { + System.err.println(ex.getMessage()); + } + } + e.printStackTrace(); + } + return ret; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof LinkedList)) { + return false; + } + if ((o != this)) { + return false; + } + if (((LinkedList) o).size() != size()) { + return false; + } + @SuppressWarnings("unchecked") + LinkedList st = ((LinkedList) o); + for (VarExpr s : this) { + if (!st.contains(s)) { + return false; + } + } + return super.equals(o); + } + + @Override + public int hashCode() { + return size(); + } + + public Expression get(VarNode var){ + for(VarExpr ve:this){ + if(ve.getVar() == var)return ve.getExpr(); + } + return null; + } + + public VarExprList copy(HashMap variables){ + VarExprList copy = new VarExprList(); + for(VarExpr v : this){ + copy.add(v.copy(variables)); + } + + return copy; + } + + @Override + public VarExprList clone(){ + return new VarExprList(); + } + +// public VarExprList clone(DualHashMap dhm) { +// return new VarExprList(this,dhm); +// } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarSet.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarSet.java new file mode 100644 index 000000000..2b95788c3 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarSet.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package edu.utah.ece.async.lema.verification.platu.platuLpn; + +import java.util.Arrays; +import java.util.HashSet; + +/** + * + * @author ldtwo + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class VarSet extends HashSet { + + /** + * + */ + private static final long serialVersionUID = 1L; + +public VarSet(HashSet in) { + super(in); + } + + public VarSet(String[] in) { + super(Arrays.asList(in)); + } + + public VarSet() { + super(0); + } + + @Override + public VarSet clone() { + VarSet set=new VarSet(); + set.addAll(this); + return set; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarType.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarType.java new file mode 100644 index 000000000..3b581eb17 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarType.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.platuLpn; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public enum VarType { + INPUT, OUTPUT, INTERNAL, GLOBAL +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarVal.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarVal.java new file mode 100644 index 000000000..cb61d4f55 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarVal.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package edu.utah.ece.async.lema.verification.platu.platuLpn; + + +/** + * + * @author ldtwo + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class VarVal { + +public static int [] counts=new int[10]; + private final String var; + private double intValue; + + public VarVal(String strVariable, double intValue) { + this.var = strVariable; + this.intValue = intValue; + counts[0]++; + } + + final boolean compareTo(final VarVal other) { + counts[1]++; + return getIntValue() == other.getIntValue() && getVariable().compareTo(other.getVariable()) == 0; + } + + void setVal(double val) { + setIntValue(val); + counts[2]++; + } + + @Override + final public String toString() { + return "(" + getVariable() + ", " + getIntValue() + ")"; + } + + /** + * @return the strVariable + */ + public String getVariable() { + return var; + } + + /** + * @return the intValue + */ + public double getIntValue() { + return intValue; + } + + /** + * @param intValue the intValue to set + */ + public void setIntValue(double intValue) { + this.intValue = intValue; + } + static public void printUsageStats(){ + System.out.printf("%-20s %11s\n", "VarVal", counts[0]); +// System.out.printf("\t%-20s %11s\n", "compareTo", counts[1]); +// System.out.printf("\t%-20s %11s\n", "setVal", counts[2]); +// System.out.printf("\t%-20s %11s\n", "", counts[3]); +// System.out.printf("\t%-20s %11s\n", "", counts[4]); +// System.out.printf("\t%-20s %11s\n", "", counts[5]); +// System.out.printf("\t%-20s %11s\n", "", counts[6]); +// System.out.printf("\t%-20s %11s\n", "", counts[7]); +// System.out.printf("\t%-20s %11s\n", "", counts[8]); +// System.out.printf("\t%-20s %11s\n", "", counts[9]); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarValSet.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarValSet.java new file mode 100644 index 000000000..943cc2145 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/VarValSet.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package edu.utah.ece.async.lema.verification.platu.platuLpn; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; + +/** + * + * @author ldtwo + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class VarValSet extends HashSet { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public VarValSet(String list) { + super(); + list = list.replace(" ", ""); + String[] tmp = list.split(",\\("); + String[] vv; + for (String s : tmp) { + if (s.length() == 0) { + continue; + } + // System.out.println("VV="+s.replace("(", "").replace(")", "")); + vv = s.replace("(", "").replace(")", "").split(","); + add(new VarVal(vv[0], new Integer(vv[1]))); + } + } + + public VarValSet() {//empty set + super(); + } + + public VarValSet(HashSet retIn) { + super(); + String[] vv; + for (String s : retIn) { + if (s.length() == 0) { + continue; + } + System.err.println("VV=" + s.replace("(", "").replace(")", "")); + vv = s.replace("(", "").replace(")", "").split(","); + add(new VarVal(vv[0], new Integer(vv[1]))); + } + } + + VarValSet(VarValSet vvs) { + super(vvs); + } + +// VarValSet(VarSet inputs, StateVector initState) { +// super(inputs.size()); +// Iterator it = inputs.iterator(); +// String var; +// double i=Double.NEGATIVE_INFINITY; +// while (it.hasNext()) { +// var = it.next(); +// i = (double)(int)initState.get(var); +// if (i == Double.NEGATIVE_INFINITY) { +// System.err.println(" VarValSet(VarSet inputs, StateVector initState):\n\t" +// + "var=" + var + "\n\ti=-1"); +// } +// //if( Main.ALL_VARS.contains(var)) +// Main.ALL_VARS.add(var); +// add(new VarVal(var, i)); +// } +// } + + public double get(String s) { + for (VarVal vv : this) { + if (vv.getVariable().compareTo(s) == 0) { + return vv.getIntValue(); + } + } + return (0); + } + + public VarVal get(VarVal otherVV) { +// if(contains(otherVV)){ +// add(otherVV);return otherVV; +// } + for (VarVal someVV : this) { + if (someVV.getVariable().compareTo(otherVV.getVariable()) == 0 && someVV.getIntValue() == otherVV.getIntValue()) { + return someVV; + } + } + return null; + } + + @Override + public String toString() { + Iterator it = iterator(); + String ret = ""; + VarVal v; + while (it.hasNext()) { + v = it.next(); + if (it.hasNext()) { + ret += v.getVariable() + " = " + v.getIntValue() + ";"; + } else { + ret += v.getVariable() + " = " + v.getIntValue(); + } + }//x=this.size()-1 ; + return ret; + } + + @Override + public boolean addAll(Collection vvc) { + Iterator it = vvc.iterator(); + VarVal vv; + boolean ret = true; + while (it.hasNext()) { + vv = it.next(); + ret &= add(vv); + } + return ret; + } + + @Override + public boolean add(VarVal vv) { + //if (null == get(vv)) + { + return super.add(vv); + } + //return false; + } + + @Override + public boolean remove(Object o) { + return super.remove(get((VarVal) o)); + } + + @Override + public boolean removeAll(Collection vvc) { + Iterator it = vvc.iterator(); + Object vv; + boolean ret = true; + while (it.hasNext()) { + vv = it.next(); + ret &= remove(vv); + } + return ret; + } + +// public StateVector toStateVector() { +// StateVector sv = new StateVector(); +// for (VarVal vv : this) { +// sv.put(vv.getVariable(), (int)vv.getIntValue()); +// } +// return sv; +// } + + @Override + public VarValSet clone(){ + return new VarValSet(this); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/Instance.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/Instance.java new file mode 100644 index 000000000..e540ebb32 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/Instance.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.platuLpn.io; + +import java.util.List; + + +public class Instance { + private String name = ""; + private String lpnLabel = null; + private List variableList = null; + private List moduleList = null; + + public Instance(String lpnLabel, String name, List varList, List modList){ + this.name = name; + this.lpnLabel = lpnLabel; + this.variableList = varList; + this.moduleList = modList; + } + + public String getName(){ + return this.name; + } + + public String getLpnLabel(){ + return this.lpnLabel; + } + + public List getVariableList(){ + return this.variableList; + } + + public List getModuleList(){ + return this.moduleList; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuGrammar.g b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuGrammar.g new file mode 100644 index 000000000..b8591cb8f --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuGrammar.g @@ -0,0 +1,1407 @@ +grammar PlatuGrammar; + +options { + language = Java; +} + +@header{ + package verification.platu.lpn.io; + + import java.util.Map.Entry; + import java.util.HashMap; + import java.util.LinkedList; + import java.util.HashSet; + import java.util.Set; + import java.util.Arrays; + import verification.platu.lpn.LPN; + import verification.platu.lpn.VarSet; + import verification.platu.lpn.LpnTranList; + import verification.platu.lpn.LPNTran; + import verification.platu.lpn.DualHashMap; + import verification.platu.lpn.VarExpr; + import verification.platu.lpn.VarExprList; + import verification.platu.stategraph.StateGraph; + import verification.platu.project.Project; + import verification.platu.expression.*; + + import lpn.parser.LhpnFile; + import lpn.parser.Place; + import lpn.parser.Transition; + import lpn.parser.Variable; + import lpn.parser.ExprTree; + + + +} + +@members{ + // static variables + static private int INFINITY = Integer.MAX_VALUE; + static private boolean main = false; +// static private ExprTree ZERO = new ExprTree("false"); // constant false node +// static private ExprTree ONE = new ExprTree("true"); // constant true node + static private HashMap LpnMap = new HashMap(); // all modules parsed, keyed by module name + static private HashMap GlobalVarHashMap = new HashMap(); // global variables and associated values + static private HashMap GlobalOutputMap = new HashMap(); // maps potential output variables to associated lpn + static private HashMap GlobalInterfaceMap = new HashMap(); // maps variables to initial values, input have null value until associated output is found + static private HashMap> GlobalInputMap = new HashMap>(); // maps input variables to associated lpn + static private HashMap> GlobalTranMap = new HashMap>(); // maps potential output variables to lpn transitions which affect it + static private HashMap GlobalVarNodeMap = new HashMap(); // maps global variable name to variable object + //static private ExpressionNode ZERO = new ConstNode("FALSE", 0); + //static private ExpressionNode ONE = new ConstNode("TRUE", 1); // constant true node + //static private Expression TrueExpr = new Expression(ONE); // constant true expression +// static private HashMap LpnMap = new HashMap(); // all modules parsed, keyed by module name +// static private HashMap GlobalVarHashMap = new HashMap(); // global variables and associated values +// static private HashMap GlobalOutputMap = new HashMap(); // maps potential output variables to associated lpn +// static private HashMap GlobalInterfaceMap = new HashMap(); // maps variables to initial values, input have null value until associated output is found +// static private HashMap> GlobalInputMap = new HashMap>(); // maps input variables to associated lpn +// static private HashMap> GlobalTranMap = new HashMap>(); // maps potential output variables to lpn transitions which affect it +// static private HashMap GlobalVarNodeMap = new HashMap(); // maps global variable name to variable object + + static private HashSet initMarkedPlaces = new HashSet(); + //static private HashSet initMarkedPlaces = new HashSet(); + + // non-static variables + private boolean Instance = false; + private HashMap VarNodeMap = null; // maps variable name to variable object + private HashMap ArrayNodeMap = null; // maps array variable name to variable object + private DualHashMap VarIndexMap = null; // maps variables to an array index + private HashMap GlobalConstHashMap = new HashMap(); // global constants within a single lpn file + private HashMap ConstHashMap = null; // constants within a single module + private HashMap StatevectorMap = null; // module variables mapped to initial values + private HashMap VarCountMap = null; // count of the references to each module variable + private List inputTranList = null; // list of lpn transitions which affect a modules input + private List outputTranList = null; // list of lpn transitions which affect a modules output + private VarSet Inputs = null; // module inputs + private VarSet Internals = null; // module internal variables + private VarSet Outputs = null; // module outputs + private int VariableIndex = 0; // count of index assigned to module variables + private int TransitionIndex = 0; + private int GlobalCount = 0; // number of global variables defined in this lpn file + private int GlobalSize = 0; // number of global variables defined + private String curLpn = ""; +// private boolean Instance = false; +// private HashMap VarNodeMap = null; // maps variable name to variable object +// private HashMap ArrayNodeMap = null; // maps array variable name to variable object +// private DualHashMap VarIndexMap = null; // maps variables to an array index +// private HashMap GlobalConstHashMap = new HashMap(); // global constants within a single lpn file +// private HashMap ConstHashMap = null; // constants within a single module +// private HashMap StatevectorMap = null; // module variables mapped to initial values +// private HashMap VarCountMap = null; // count of the references to each module variable +// private List inputTranList = null; // list of lpn transitions which affect a modules input +// private List outputTranList = null; // list of lpn transitions which affect a modules output +// private VarSet Inputs = null; // module inputs +// private VarSet Internals = null; // module internal variables +// private VarSet Outputs = null; // module outputs + + public enum VarType { + INPUT, OUTPUT, INTERNAL, GLOBAL + } +} + +@rulecatch{ + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } +} + +@lexer::header{ + package verification.platu.lpn.io; +} + +//parseLpnFile[Project prj, boolean instance, HashMap portMap] returns [Set lpnSet] +// : +// ; + +//lpn[Project prj] returns [Set lpnSet] + lpn returns [Set lpnSet]// + : {$lpnSet = new HashSet();}//{$lpnSet = new HashSet();} + ((globalConstants globalVariables) | (globalVariables globalConstants) | (globalVariables) | (globalConstants))? + { + // check that global constants are consistently defined in each lpn file + if(GlobalSize > 0 && GlobalCount != GlobalSize){ + System.err.println("error: global variable definitions are inconsistent"); + System.exit(1); + } + } + (module //module[prj] + { + $lpnSet.add($module.lpn); + } + | main //main[prj] + { + + } + )+ EOF + ; + +main // [Project prj] + : '<' 'mod' 'name' '=' '"' 'main' '"' '>' + { + if(main == true){ + System.err.println("error"); + System.exit(1); + } + + main = true; + } + instantiation+ '<' '/' 'mod' '>' + ; + +// TODO: don't enforce order +//module[Project prj] returns [LPN lpn] +module returns [LhpnFile lpn] + : ( '<' 'mod' 'name' '=' '"' ID + { + // module names must be unique + if(LpnMap.containsKey($ID.text)){ + System.err.println("error on line " + $ID.getLine() + ": module " + $ID.text + " already exists"); + System.exit(1); + } + + // initialize non static variables for new module + VarIndexMap = new DualHashMap(); + ConstHashMap = new HashMap(); + VarNodeMap = new HashMap(); + // TODO: Array Nodes + ArrayNodeMap = new HashMap(); + VarCountMap = new HashMap(); + Inputs = new VarSet(); + Internals = new VarSet(); + Outputs = new VarSet(); + inputTranList = new ArrayList();//inputTranList = new ArrayList(); + outputTranList = new ArrayList();//outputTranList = new ArrayList(); + StatevectorMap = new HashMap(); + VariableIndex = 0; + System.out.println("-------------------------"); + System.out.println("mod = " + $ID.text); + } + '"' '>' constants? variables instantiation? logic? '<' '/' 'mod' '>' + { + for(Entry e : VarCountMap.entrySet()){ + if(e.getValue() == 0){ + System.out.println("warning: variable '" + e.getKey() + "' is never assigned"); + } + } + + // create new lpn +// Zone zone; +// if (Main.ZONE_VERSION == 2) { +// zone = new HashedHashedMapZoneImpl(); +// } +// else if (Main.ZONE_VERSION == 3) { +// zone = new HashedHashedMapZoneImpl(); +// } +// else { +// zone = new HashedHashedMapZoneImpl(); +// } + +// int i = 0; +// int[] initialMarking = new int[$logic.initMarking.size()]; +// for(Integer mark : $logic.initMarking){ +// initialMarking[i++] = mark; +// } + +// $lpn = new LPN(prj, $ID.text, Inputs, Outputs, Internals, VarNodeMap, $logic.lpnTranSet, +// StatevectorMap, initialMarking); + $lpn = new LhpnFile(); + $lpn.setLabel($ID.text); + System.out.println("---- LPN : " + $lpn.getLabel() + " ----"); + for (Transition t: $logic.lpnTranSet) { + $lpn.addTransition(t); + t.setLpn($lpn); + System.out.println("transition(logic): " + t.getLabel()); + for (Place p : t.getPreset()) { + if ($logic.initMarking.contains(p.getName())) + $lpn.addPlace(p.getName(), true); + else + $lpn.addPlace(p.getName(), false); + $lpn.getPlace(p.getName()).addPostset(t); + } + for (Place p : t.getPostset()) { + if ($logic.initMarking.contains(p.getName())) + $lpn.addPlace(p.getName(), true); + else + $lpn.addPlace(p.getName(), false); + $lpn.getPlace(p.getName()).addPreset(t); + } + } + +// for(Transition tran : inputTranList){ +// tran.addDstLpn($lpn); +// } +// $lpn.addAllInputTrans(inputTranList); +// $lpn.addAllOutputTrans(outputTranList); +// $lpn.setVarIndexMap(VarIndexMap); +// $logic.lpnTranSet.setLPN($lpn); +// prj.getDesignUnitSet().add($lpn.getStateGraph()); + +// for (Transition t : inputTranList) { +// System.out.println("transition(in): " + t.getLabel()); +// $lpn.addTransition(t); +// } + for (Transition t : outputTranList) { + System.out.println("transition(out): " + t.getLabel()); + $lpn.addTransition(t); + } + + LpnMap.put($lpn.getLabel(), $lpn); +// for (String var : StatevectorMap.keySet()) { +// $lpn.addInteger(var, StatevectorMap.get(var)+""); +// } + + // TODO: Where to use these hashmaps? + // map outputs to lpn object + for(String output : Outputs){ + GlobalOutputMap.put(output, $lpn); + $lpn.addOutput(output, "integer", StatevectorMap.get(output)+""); + System.out.println("@1: Added output variable " + output + " to LPN " + $lpn.getLabel()); + } + // map potential output to lpn object + for(String internal : Internals){ + GlobalOutputMap.put(internal, $lpn); + $lpn.addInternal(internal, "integer", StatevectorMap.get(internal)+""); + System.out.println("@1: Added internal variable " + internal + " to LPN " + $lpn.getLabel() + "with initial value " + StatevectorMap.get(internal)); + } + // map input variable to lpn object + for(String input : Inputs) { + if(GlobalInputMap.containsKey(input)){ + GlobalInputMap.get(input).add($lpn); + $lpn.addInput(input, "integer", StatevectorMap.get(input)+""); + System.out.println("@1: Added input variable " + input + " to LPN " + $lpn.getLabel() + " with initial value " + StatevectorMap.get(input) + "."); + } + else{ + List lpnList = new ArrayList();//List lpnList = new ArrayList(); + lpnList.add($lpn); + GlobalInputMap.put(input, lpnList); + $lpn.addInput(input, "integer", StatevectorMap.get(input)+""); + System.out.println("@2: Added input variable " + input + " to LPN " + $lpn.getLabel() + " with initial value " + StatevectorMap.get(input) + "."); + } + } + + } + ) + ; + +constants + : '<' 'const' '>' (const1=ID '=' val1=INT + { + // make sure constant is not defined as something else +// String const1_tmp = $const1.text; +// if ($const1.text.contains(".")) { +// const1_tmp.replaceAll(".", "_"); +// } +// else { +// const1_tmp = $const1.text; +// } + + String const1_tmp = $const1.text; + if ($const1.text.contains(".")) { + const1_tmp = const1_tmp.replace(".", "_"); + } + else { + const1_tmp = $const1.text; + } + if(StatevectorMap.containsKey(const1_tmp)){ + System.err.println("error on line " + $const1.getLine() + ": " + $const1.text + " already exists as a variable"); + System.exit(1); + } + else if(GlobalConstHashMap.containsKey(const1_tmp)){ + System.err.println("error on line " + $const1.getLine() + ": " + $const1.text + " already exists as a global constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey(const1_tmp)){ + System.err.println("error on line " + $const1.getLine() + ": " + $const1.text + " is already defined as a global variable"); + System.exit(1); + } + // put will override previous value + //Integer result = ConstHashMap.put($const1.text, Integer.parseInt($val1.text)); + Integer result = ConstHashMap.put(const1_tmp, Integer.parseInt($val1.text)); + if(result != null){ + System.err.println("warning on line " + $const1.getLine() + ": " + $const1.text + " will be overwritten"); + } + } + ';')* '<' '/' 'const' '>' + ; + +globalConstants + : '<' 'const' '>' (const1=ID '=' val1=INT + { + String const1_tmp = $const1.text; + if ($const1.text.contains(".")) { + const1_tmp = const1_tmp.replace(".", "_"); + } + else { + const1_tmp = $const1.text; + } + // make sure constant has not been defined already + if(GlobalVarHashMap.containsKey(const1_tmp)){ + System.err.println("error on line " + $const1.getLine() + ": " + $const1.text + " is already defined as a global variable"); + System.exit(1); + } + + // put will override previous value + Integer result = GlobalConstHashMap.put(const1_tmp, Integer.parseInt($val1.text)); + if(result != null){ + System.err.println("warning on line " + $const1.getLine() + ": " + $const1.text + " will be overwritten"); + } + } + ';')* '<' '/' 'const' '>' + ; + +globalVariables + : '<' 'var' '>' (var=ID + { + // make sure global variables are consistently defined in each lpn file + String var_tmp = $var.text; + if ($var.text.contains(".")) { + var_tmp = var_tmp.replace(".", "_"); + } + else { + var_tmp = $var.text; + } + if(GlobalSize == 0){ + if(GlobalConstHashMap.containsKey(var_tmp)){ + System.err.println("error on line" + $var.getLine() + ": " + $var.text + "already exists as a constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey(var_tmp)){ + System.err.println("error on line " + $var.getLine() + ": " + $var.text + " has already been defined"); + System.exit(1); + } + } + else{ + if(!GlobalVarHashMap.containsKey(var_tmp)){ + System.err.println("error on line " + $var.getLine() + ": " + $var.text + " is inconsistently defined"); + System.exit(1); + } + } + + GlobalCount++; + } + '=' (val=INT + { + // make sure global variables are consistently initialized + int value = Integer.parseInt($val.text); + if(GlobalSize == 0){ + GlobalVarHashMap.put(var_tmp, value); + } + else{ + int globalVal = GlobalVarHashMap.get(var_tmp); + if(globalVal != value){ + System.err.println("error on line " + $val.getLine() + ": " + $var.text + " is inconsistently assigned"); + System.exit(1); + } + } + } + | var2=ID + { + String var2_tmp = $var2.text; + if ($var2.text.contains(".")) { + var2_tmp = var2_tmp.replace(".", "_"); + } + else { + var2_tmp = $var2.text; + } + // get value of variable + Integer value = null; + if(GlobalConstHashMap.containsKey(var2_tmp)){ + value = GlobalConstHashMap.get(var2_tmp); + } + else if(GlobalVarHashMap.containsKey(var2_tmp)){ + System.err.println("error on line " + $var2.getLine() + ": global variable " + $var2.text + " cannot be assigned to global variable " + $var.text); + System.exit(1); + } + else{ + System.err.println("error on line " + $var2.getLine() + ": " + $var2.text + " is not defined"); + System.exit(1); + } + // make sure global variable is consistently initialized + if(GlobalSize == 0){ + GlobalVarHashMap.put(var2_tmp, value); + } + else{ + int globalVal = GlobalVarHashMap.get(var2_tmp); + if(globalVal != value){ + System.err.println("error on line " + $val.getLine() + ": " + $var.text + " is inconsistently assigned"); + System.exit(1); + } + } + } + )';')* '<' '/' 'var' '>' + ; + +//TODO: add globals +variables + : {Integer value = null; Token varNode = null; String var_tmp;} + '<' 'var' '>' ((var=ID + { + // check variable is unique in scope + var_tmp = $var.text; + if ($var.text.contains(".")) { + var_tmp = var_tmp.replace(".", "_"); + } + else { + var_tmp = $var.text; + } + if(GlobalConstHashMap.containsKey(var_tmp)){ + System.err.println("error on line " + $var.getLine() + ": " + $var.text + " is a global constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey(var_tmp)){ + System.err.println("error on line " + $var.getLine() + ": " + $var.text + " is a global variable"); + System.exit(1); + } + else if(StatevectorMap.containsKey(var_tmp)){ + System.err.println("warning on line " + $var.getLine() + ": " + $var.text + " will be overwritten"); + } + varNode = var; + } + '=' (val=INT + { + // get variable initial value + value = Integer.parseInt($val.text); + } + | var2=ID + { + String var2_tmp = $var2.text; + if ($var2.text.contains(".")) { + var2_tmp = var2_tmp.replace(".", "_"); + } + else { + var2_tmp = $var2.text; + } + // get variable initial value + if(GlobalConstHashMap.containsKey(var2_tmp)){ + value = GlobalConstHashMap.get(var2_tmp); + } + else if(GlobalVarHashMap.containsKey(var2_tmp)){ + value = GlobalVarHashMap.get(var2_tmp); + } + else if(ConstHashMap.containsKey(var2_tmp)){ + value = ConstHashMap.get(var2_tmp); + } + else if(StatevectorMap.containsKey(var2_tmp)){ // Should var be allowed to assign a var? + value = StatevectorMap.get(var2_tmp); + } + else{ + System.err.println("error on line " + $var2.getLine() + ": " + $var2.text + " is not defined"); + System.exit(1); + } + + varNode = var2; + var_tmp = var2_tmp; + } + )';') + { + // add variable and value to state vector + //StatevectorMap.put(varNode.getText(), value); + StatevectorMap.put(var_tmp, value); + + // generate variable index and create new var node + int index = VariableIndex++; + //VarIndexMap.insert(varNode.getText(), index); + VarIndexMap.insert(var_tmp, index); + ExprTree newVarNode = new ExprTree(var_tmp); + newVarNode.setIntegerSignals(StatevectorMap.keySet()); + newVarNode.getExprTree(); + VarNodeMap.put(var_tmp, newVarNode); + + //VarNodeMap.put(varNode.getText(), new ExprTree(varNode.getText())); + //VarNodeMap.put(varNode.getText(), new VarNode(varNode.getText(), index)); + + // if associated input variable has been defined, label as output, else label as internal + if(!GlobalInterfaceMap.containsKey(var_tmp)){ + Internals.add(var_tmp); + } + else{ + if(GlobalInterfaceMap.get(varNode.getText()) != null){ + System.err.println("error on line " + varNode.getLine() + ": variable '" + varNode.getText() + "' has already been declared in another module"); + System.exit(1); + } + Outputs.add(var_tmp); + // TODO: Is it needed for our LPN? + // initialize associated input variables with output value + List lpnList = GlobalInputMap.get(var_tmp); + if(lpnList != null){ + for(LhpnFile lpn : lpnList){ + //lpn.getInitVector().put(varNode.getText(), value); + //(delete) lpn.addInput(var_tmp, "integer", value+""); + } + } + } + GlobalInterfaceMap.put(var_tmp, value); + VarCountMap.put(var_tmp, 0); + } + // TODO: Need to support arrays in our LPN. + | (arrayName=ID + { + List dimensionsList = new ArrayList(); + } + ('[' (dim=ID + { + // get variable value + if(GlobalConstHashMap.containsKey($dim.text)){ + value = GlobalConstHashMap.get($dim.text); + } + else if(GlobalVarHashMap.containsKey($dim.text)){ + value = GlobalVarHashMap.get($dim.text); + } + else if(ConstHashMap.containsKey($dim.text)){ + value = ConstHashMap.get($dim.text); + } + else if(StatevectorMap.containsKey($dim.text)){ // Should var be allowed to assign a var? + value = StatevectorMap.get($dim.text); + } + else{ + System.err.println("error on line " + $dim.getLine() + ": " + $dim.text + " is not defined"); + System.exit(1); + } + + dimensionsList.add(value); + } + | val2=INT + { + dimensionsList.add(Integer.parseInt($val2.text)); + } + ) ']' )+ '=' + { + List valueList = new ArrayList(); + } + ('(' (val3=INT ',' + { + valueList.add(Integer.parseInt($val3.text)); + } + )* val4=INT + { + valueList.add(Integer.parseInt($val4.text)); + } + ')' )+ ';' + { + if(valueList.size() != dimensionsList.get(0)){ + System.err.println("error: incompatible number of elements in " + $arrayName.text); + System.exit(1); + } + + if(dimensionsList.size() == 1){ + int varCount = 0; + int arraySize = dimensionsList.get(0); + List array = new ArrayList(arraySize); + for(int i = 0; i < arraySize; i++){ + String name = $arrayName.text + varCount++; + int index = VariableIndex++; + //VarNode v = new VarNode(name, index); + ExprTree v = new ExprTree(name); + array.add(v); + + // add variable and value to state vector + StatevectorMap.put(name, 0); + + // generate variable index and create new var node + VarIndexMap.insert(name, index); + } + // TODO: ArrayNodeMap? +// ArrayNodeMap.put($arrayName.text, new ArrayNode($arrayName.text, array, 1)); + VarCountMap.put($arrayName.text, 0); + } + else{ + } + } + ))* '<' '/' 'var' '>' + { + // add global variables to initial state vector and label as an input & output + System.out.println("GlobalVarHashMap size = " + GlobalVarHashMap.size()); + for(Entry e : GlobalVarHashMap.entrySet()){ + String globalVar = e.getKey(); + StatevectorMap.put(globalVar, e.getValue()); + Integer index = VariableIndex++; + VarIndexMap.insert(globalVar, index); + //VarNodeMap.put(globalVar, new VarNode(globalVar, index)); + VarNodeMap.put(globalVar, new ExprTree(globalVar)); + Inputs.add(globalVar); + System.out.println("Added globalVar (" + globalVar + ") to Inputs."); + Outputs.add(globalVar); + } + } + ; + +// TODO: implement instantiation +instantiation + : {HashMap portMap = new HashMap();} + '<' 'inst' '>' + modName=ID instName=ID '('(mod=ID '.' var=ID)+ ')' + '<' '/' 'inst' '>' + ; + +logic returns [List initMarking, LpnTranList lpnTranSet]//[List initMarking, LpnTranList lpnTranSet] + : {$lpnTranSet = new LpnTranList();} + marking (transition {$lpnTranSet.add($transition.lpnTran);})+ + { + $initMarking = $marking.mark; + } + ; + +marking returns [List mark] //[List mark] + : {$mark = new LinkedList(); Integer result;} + ('<' 'marking' '>' ((m1=INT + { +// $mark.add(Integer.parseInt($m1.text)); +// initMarkedPlaces.add(Integer.parseInt($m1.text)); + $mark.add("p" + $m1.text); + initMarkedPlaces.add("p" + $m1.text); + } + | c1=ID + { + String c1_tmp = $c1.text; + if ($c1.text.contains(".")) { + c1_tmp = c1_tmp.replace(".", "_"); + } + else { + c1_tmp = $c1.text; + } +// result = ConstHashMap.get(c1_tmp); +// if(result == null){ +// System.err.println("error on line " + $c1.getLine() + ": " + $c1.text + " is not a valid constant"); +// System.exit(1); +// } +// $mark.add(result); +// initMarkedPlaces.add(Integer.parseInt($m1.text)); + $mark.add(c1_tmp); + initMarkedPlaces.add(c1_tmp); + } + ) (',' (m2=INT + { +// $mark.add(Integer.parseInt($m2.text)); +// initMarkedPlaces.add(Integer.parseInt($m2.text)); + $mark.add("p"+$m2.text); + initMarkedPlaces.add("p" +$m2.text); + + } + | c2=ID + { + String c2_tmp = $c2.text; + if ($c2.text.contains(".")) { + c2_tmp = c2_tmp.replace(".", "_"); + } + else { + c2_tmp = $c2.text; + } +// result = ConstHashMap.get(c2_tmp); +// if(result == null){ +// System.err.println("error on line " + $c2.getLine() + ": " + $c2.text + " is not a valid constant"); +// System.exit(1); +// } +// $mark.add(result); +// initMarkedPlaces.add(result); + $mark.add(c2_tmp); + initMarkedPlaces.add(c2_tmp); + } + ))*)? '<' '/' 'marking' '>')? + ; + +transition returns [Transition lpnTran]// [LPNTran lpnTran] + : { + Integer result = null; + //ArrayList presetList = new ArrayList(); +// VarExprList assignmentList = new VarExprList(); +// ArrayList assertionList = new ArrayList(); +// Expression guardExpr = TrueExpr; +// int delayLB = 0; +// int delayUB = INFINITY; +// boolean local = true; + + ArrayList presetList = new ArrayList(); + ArrayList postsetList = new ArrayList(); + HashMap assignmentList = new HashMap(); + // TODO: Need to deal with assertionList + //ArrayList assertionList = new ArrayList(); + ArrayList assertionList = new ArrayList(); + ExprTree guardExpr = null; + int delayLB = 0; + int delayUB = INFINITY; + boolean local = true; + + } + '<' 'transition' 'label' '=' '"' lbl=(ID|INT) '"' 'preset' '=' ('"' '"' | ('"' (pre=INT + { + //presetList.add(Integer.parseInt($pre.text)); + if ($pre!=null && initMarkedPlaces.contains(Integer.parseInt($pre.text))) + presetList.add(new Place("p"+$pre.text, true)); + else + presetList.add(new Place("p"+$pre.text, false)); + } + | pre1=ID + { + String pre1_tmp = $pre1.text; + if ($pre1.text.contains(".")) { + pre1_tmp = pre1_tmp.replace(".", "_"); + } + else { + pre1_tmp = $pre1.text; + } + result = ConstHashMap.get(pre1_tmp); + if(result == null){ + System.err.println("error on line " + $pre1.getLine() + ": " + $pre1.text + " is not a constant"); + System.exit(1); + } + //presetList.add(result); + if (initMarkedPlaces.contains(result)) + presetList.add(new Place("p"+result, true)); + else + presetList.add(new Place("p"+result, false)); + } + ) ( ',' pre2=INT + { + //presetList.add(Integer.parseInt($pre2.text)); + if ($pre2!=null && initMarkedPlaces.contains(Integer.parseInt($pre2.text))) + presetList.add(new Place("p"+$pre2.text, true)); + else + presetList.add(new Place("p"+$pre2.text, false)); + } + | ',' pre3=ID + { + String pre3_tmp = $pre3.text; + if ($pre3.text.contains(".")) { + pre3_tmp = pre3_tmp.replace(".", "_"); + } + else { + pre3_tmp = $pre3.text; + } + result = ConstHashMap.get(pre3_tmp); + if(result == null){ + System.err.println("error on line " + $pre3.getLine() + ": " + $pre3.text + " is not a constant"); + System.exit(1); + } + //presetList.add(result); + if ($pre3!=null && initMarkedPlaces.contains(Integer.parseInt($pre3.text))) + presetList.add(new Place("p"+result, true)); + else + presetList.add(new Place("p"+result, false)); + } + )* '"')) 'postset' '=' ( '"' '"' | ('"' ( post=INT + { + //postsetList.add(Integer.parseInt($post.text)); + if ($post!=null && initMarkedPlaces.contains(Integer.parseInt($post.text))) + postsetList.add(new Place("p"+$post.text, true)); + else + postsetList.add(new Place("p"+$post.text, false)); + } + | post1=ID + { + String post1_tmp = $post1.text; + if ($post1.text.contains(".")) { + post1_tmp = post1_tmp.replace(".", "_"); + } + else { + post1_tmp = $post1.text; + } + result = ConstHashMap.get(post1_tmp); + if(result == null){ + System.err.println("error on line " + $post1.getLine() + ": " + $post1.text + " is not a constant"); + System.exit(1); + } + //postsetList.add(result); + if (initMarkedPlaces.contains(result)) + postsetList.add(new Place("p"+result, true)); + else + postsetList.add(new Place("p"+result, false)); + } + ) + ( (',' post2=INT) + { + //postsetList.add(Integer.parseInt($post2.text)); + if ($post2!=null && initMarkedPlaces.contains(Integer.parseInt($post2.text))) + postsetList.add(new Place("p"+$post2.text, true)); + else + postsetList.add(new Place("p"+$post2.text, false)); + } + | (','post3=ID) + { + String post3_tmp = $post3.text; + if ($post3.text.contains(".")) { + post3_tmp = post3_tmp.replace(".", "_"); + } + else { + post3_tmp = $post3.text; + } + result = ConstHashMap.get(post3_tmp); + if(result == null){ + System.err.println("error on line " + $post3.getLine() + ": " + $post3.text + " is not a constant"); + System.exit(1); + } +// postsetList.add(result); + if (initMarkedPlaces.contains(result)) + postsetList.add(new Place("p"+result, true)); + else + postsetList.add(new Place("p"+result, false)); + } + )* '"' )) '>' (guard + { + guardExpr = $guard.expr; + } + )? (delay + { + // TODO: ignored delay for untimed models + delayLB = $delay.delayLB; + delayUB = $delay.delayUB; + } + )? ((assertion + { + // TODO: ignored assertions temporarily + if($assertion.booleanExpr != null){ + assertionList.add($assertion.booleanExpr); + } + } + ) | (assignment + { + assignmentList.putAll($assignment.assign); + } + ))* '<' '/' 'transition' '>' + { + // create new lpn transitions and add assertions + // $lpnTran = new LPNTran($lbl.text, TransitionIndex++, presetList, postsetList, guardExpr, assignmentList, delayLB, delayUB, local); + $lpnTran = new Transition(); + $lpnTran.setName("t" + $lbl.text); + $lpnTran.setIndex(TransitionIndex++); + for (Place p: presetList) { + $lpnTran.addPreset(p); + } + for (Place p: postsetList) { + $lpnTran.addPostset(p); + } + $lpnTran.addEnablingWithoutLPN(guardExpr); + for (String var : assignmentList.keySet()) { + $lpnTran.addIntAssign(var, assignmentList.get(var)); + } + + // TODO: Add assertionList to the new lpn transition +// if(assertionList.size() > 0){ +// $lpnTran.addAllAssertions(assertionList); +// } + + // add non-local transition to associated LPNs + for(String var : assignmentList.keySet()){ + if(Outputs.contains(var)){ + // local is determined by isLocal() in Transition.java + local = false; +// if(GlobalInputMap.containsKey(var)){ +// for(LhpnFile lpn : GlobalInputMap.get(var)){ +// lpn.addInputTran($lpnTran); +// // dstLpn is added by setDstLpnList in Transition.java +// $lpnTran.addDstLpn(lpn); +// } +// } + } + + // map lpn transition with output and potential outuput variables + if(GlobalTranMap.containsKey(var)){ + GlobalTranMap.get(var).add($lpnTran); + System.out.println("Add "+ $lpnTran.getLabel() + " to variable " + var); + } + else{ + List tranList = new ArrayList(); + tranList.add($lpnTran); + GlobalTranMap.put(var, tranList); + System.out.println("Create tranList for variable " + var + ", and add " + $lpnTran.getLabel() + " to it."); + + } + } + +// $lpnTran.setLocal(local); + if(local == false){ + outputTranList.add($lpnTran); + } + } + ; + +assertion returns [ExprTree booleanExpr]//[Expression booleanExpr] + : {booleanExpr = null;// TODO: assertion + } + 'assert' '(' expression ')' ';' + { + //$booleanExpr = new Expression($expression.expr); + $booleanExpr = new ExprTree($expression.expr); + } + ; + +guard returns [ExprTree expr]//[Expression expr] + : expression ';' + { + //$expr = new Expression($expression.expr); + $expr = new ExprTree($expression.expr); + } + ; + +delay returns [int delayLB, int delayUB] + : '(' lb=INT + { + $delayLB = Integer.parseInt($lb.text); + } + ',' (ub=INT + { + $delayUB = Integer.parseInt($ub.text); + // make sure delays are >= 0 and upper bound is >= lower bound + if($delayLB < 0){ + System.err.println("error on line " + $lb.getLine() + ": lower bound " + $delayLB + " must be >= 0"); + System.exit(1); + } + else if($delayLB == INFINITY){ + System.err.println("error on line " + $ub.getLine() + ": lower bound " + $delayUB + " must be a non-negative finite number"); + System.exit(1); + } + else if($delayUB < $delayLB){ + System.err.println("error on line " + $ub.getLine() + ": upper bound " + $delayUB + " < lower bound " + $delayLB); + System.exit(1); + } + } + | 'inf' + { + $delayUB = INFINITY; + } + ) ')' ';' + ; + +assignment returns [HashMap assign]//[VarExpr assign] + : (var=ID '=' + { + String var_tmp = $var.text; + if ($var.text.contains(".")) { + var_tmp = var_tmp.replace(".", "_"); + } + else { + var_tmp = $var.text; + } + // make sure only global, internal and output variables are assigned + if(GlobalConstHashMap.containsKey(var_tmp)){ + System.err.println("error on line " + $var.getLine() + ": global constant " + $var.text + " cannot be assigned"); + System.exit(1); + } + else if(ConstHashMap.containsKey(var_tmp)){ + System.err.println("error on line " + $var.getLine() + ": constant " + $var.text + " cannot be assigned"); + System.exit(1); + } + else if(!Outputs.contains(var_tmp) && !Internals.contains(var_tmp)){ + System.err.println("error on line " + $var.getLine() + ": input variable " + $var.text + " cannot be assigned"); + System.exit(1); + } + } + expression ';' + { + Integer varCount = VarCountMap.get(var_tmp); + if(varCount != null){ + VarCountMap.put(var_tmp, ++varCount); + } + +// Expression expr = new Expression($expression.expr); +// $assign = new VarExpr(VarNodeMap.get($var.text), expr); + + ExprTree expr = new ExprTree($expression.expr); + $assign = new HashMap(); + $assign.put(var_tmp, expr); + } + //TODO: Need to support array assignment + ) | (var2=ID + { + List indexList = new ArrayList(); + + } + ('[' (INT | ID) ']')+ '=' expression ';' + { + } + ) + ; + +// Expressions +term returns [ExprTree expr] //[ExpressionNode expr] + : ID + { + String ID_tmp = $ID.text; + if ($ID.text.contains(".")) { + ID_tmp = ID_tmp.replace(".", "_"); + } + else { + ID_tmp = $ID.text; + } + if(ConstHashMap.containsKey(ID_tmp)){ + //$expr = new ConstNode($ID.text, ConstHashMap.get($ID.text)); + $expr = new ExprTree(ConstHashMap.get(ID_tmp)+""); + } + else if(GlobalConstHashMap.containsKey(ID_tmp)){ + //$expr = new ConstNode($ID.text, GlobalConstHashMap.get($ID.text)); + $expr = new ExprTree(GlobalConstHashMap.get(ID_tmp)+""); + } + else if(StatevectorMap.containsKey(ID_tmp)){ + //$expr = VarNodeMap.get($ID.text); + $expr = VarNodeMap.get(ID_tmp); + } + else{ // identify new input variable +// // create expression +// $expr = new platu.lpn.io.expression.VarNode($ID.text); + + // label as input and initialize to 0 + StatevectorMap.put(ID_tmp, 0); + System.out.println("label (" + ID_tmp + ") as input and initialize to 0. Added to Inputs."); + Inputs.add(ID_tmp); + for (String input : Inputs) { + System.out.println("@3: input = " + input); + } + + // identify new input variable + // create expression + ExprTree newVarNode = new ExprTree(ID_tmp); + newVarNode.setIntegerSignals(StatevectorMap.keySet()); + $expr = newVarNode.getExprTree(); + VarNodeMap.put(ID_tmp, newVarNode); + +// int index = VariableIndex++; +// VarIndexMap.insert($ID.text, index); +// VarNode newVarNode = new VarNode($ID.text, index); +// VarNodeMap.put($ID.text, newVarNode); +// $expr = newVarNode; + + // if associated output variable has not been defined insert with null value, + // otherwise get output variable and relabel from internal to output, + // get output value and initialize input statevector, label lpn transitions associated with output as non-local + // and add to current lpn's inputTranList + if(!GlobalInterfaceMap.containsKey(ID_tmp)){ + GlobalInterfaceMap.put(ID_tmp, null); + System.out.println("@ term, Added entry (" + ID_tmp + "null) to GlobalInterfaceMap"); + } + else{ + Integer value = GlobalInterfaceMap.get(ID_tmp); + if(value != null){ + StatevectorMap.put(ID_tmp, value); + LhpnFile outputLPN = GlobalOutputMap.get(ID_tmp); + if(outputLPN.getAllInternals().keySet().contains(ID_tmp)){ + outputLPN.getAllInternals().remove(ID_tmp); +// for (String varID : outputLPN.getAllInternals().keySet()) { +// System.out.println("@term-outputLPN: internal var " + varID + " is in LPN " + outputLPN.getLabel()); +// } + outputLPN.addOutput(ID_tmp, "integer", value+""); + //System.out.println("@term : Removed internal variable " + ID_tmp); + //System.out.println("@term : Added output variable " + ID_tmp + " to LPN " + outputLPN.getLabel()); + } + for(Transition tran : GlobalTranMap.get(ID_tmp)){ + //tran.setLocalFlag(false); + //outputLPN.addOutputTran(tran); + outputLPN.addTransition(tran); + System.out.println("@term : Added transition " + tran.getLabel() + " to LPN " + outputLPN.getLabel()); + inputTranList.add(tran); + System.out.println("@term : Added transition " + tran.getLabel() + " to inputTranList."); + System.out.println("inputTranList : "); + for (Transition t : inputTranList) { + System.out.println("Transition: " + t.getLabel()); + } + System.out.println("~~~~~~~~~~~~~"); + } + } + } + } + } + | LPAREN expression RPAREN {$expr = $expression.expr;} + | INT { //{$expr = new ConstNode("name", Integer.parseInt($INT.text));} + ExprTree tree = new ExprTree(Integer.parseInt($INT.text)+""); + $expr = tree.getExprTree(); + } + | TRUE { + ExprTree tree = new ExprTree("true"); + $expr = tree.getExprTree(); + } + | FALSE { + ExprTree tree = new ExprTree("false"); + $expr = tree.getExprTree(); + } + ; +// | TRUE {$expr = ONE;} +// | FALSE {$expr = ZERO;} +// ; + + +unary returns [ExprTree expr]//[ExpressionNode expr] + : {boolean positive = true;} + ('+' | ('-' {if(positive){ positive = false;} else {positive = true;}}))* term + { + if(!positive){ + //$expr = new MinNode($term.expr); + // TODO: Correct ExprTree for unary? + $expr = new ExprTree($term.expr, null, "U-", 'a'); + } + else{ + $expr = $term.expr; + } + } + ; + +bitwiseNegation returns [ExprTree expr] //[ExpressionNode expr] + : {boolean neg = false;} + ('~' {if(neg){neg = false;} else{neg = true;}})* unary + { + if(neg){ + //$expr = new BitNegNode($unary.expr); + $expr = new ExprTree(null, $unary.expr, "~", 'l'); + } + else{ + $expr = $unary.expr; + } + } + ; + +negation returns [ExprTree expr]//[ExpressionNode expr] + : {boolean neg = false;} + ('!' {if(neg){neg = false;} else{neg = true;}})* bitwiseNegation + { + if(neg){ + //$expr = new NegNode($bitwiseNegation.expr); + // TODO: Correct translation of negation? + $expr = new ExprTree(null, $bitwiseNegation.expr, "~", 'l'); + } + else{ + $expr = $bitwiseNegation.expr; + } + } + ; + +mult returns [ExprTree expr] //[ExpressionNode expr] + : op1=negation {$expr = $op1.expr;} + ( '*' op2=negation {$expr = new ExprTree($expr, $op2.expr, "*", 'a');}//{$expr = new MultNode($expr, $op2.expr);} + | '/' op2=negation {$expr = new ExprTree($expr, $op2.expr, "/", 'a');}//{$expr = new DivNode($expr, $op2.expr);} + // TODO: Line below fails to compile + // | '%' op2=negation {$expr = new ExprTree($expr, $op2.expr, "%", 'a');}//{$expr = new ModNode($expr, $op2.expr);} + )* + ; + +add returns [ExprTree expr] //[ExpressionNode expr] + : op1=mult {$expr = $op1.expr;} + ( '+' op2=mult {$expr = new ExprTree($expr, $op2.expr, "+", 'a');}//{$expr = new AddNode($expr, $op2.expr);} + | '-' op2=mult {$expr = new ExprTree($expr, $op2.expr, "-", 'a');}//{$expr = new SubNode($expr, $op2.expr);} + )* + ; + +shift returns [ExprTree expr]//[ExpressionNode expr] + : op1=add {$expr = $op1.expr;} + ( '<<' op2=add {$expr = new ExprTree(new ExprTree("int(" + $op1.text + ")"), new ExprTree(new ExprTree("2"), $op2.expr, "^", 'a'), "*", 'a');} + | '>>' op2=add {$expr = new ExprTree(new ExprTree("int(" + $op1.text + ")"), new ExprTree(new ExprTree("2"), $op2.expr, "^", 'a'), "/", 'a');} + )* +// ( '<<' op2=add {$expr = new LeftShiftNode($expr, $op2.expr);} +// | '>>' op2=add {$expr = new RightShiftNode($expr, $op2.expr);} +// )* + ; + +relation returns [ExprTree expr]//[ExpressionNode expr] + : op1=shift {$expr = $op1.expr;} + ( '<' op2=shift {$expr = new ExprTree($expr, $op2.expr, "<", 'r');}//{$expr = new LessNode($expr, $op2.expr);} + | '<=' op2=shift {$expr = new ExprTree($expr, $op2.expr, "<=", 'r');}//{$expr = new LessEqualNode($expr, $op2.expr);} + | '>=' op2=shift {$expr = new ExprTree($expr, $op2.expr, ">=", 'r');}//{$expr = new GreatEqualNode($expr, $op2.expr);} + | '>' op2=shift {$expr = new ExprTree($expr, $op2.expr, ">", 'r');}//{$expr = new GreatNode($expr, $op2.expr);} + )* + ; + +equivalence returns [ExprTree expr] // [ExpressionNode expr] + : op1=relation {$expr = $op1.expr;} + ( '==' op2=relation {$expr = new ExprTree($expr, $op2.expr, "=", 'r');}//{$expr = new EquivNode($expr, $op2.expr);} + // TODO: Not equal to in our LPN? + | '!=' op2=relation {$expr = new ExprTree(new ExprTree($expr, $op2.expr, "=", 'r'), null, "~", 'l');}//{$expr = new NotEquivNode($expr, $op2.expr);} + )* + ; + +bitwiseAnd returns [ExprTree expr]//[ExpressionNode expr] + : op1=equivalence {$expr = $op1.expr;} + ( '&' op2=equivalence {$expr = new ExprTree($expr, $op2.expr, "&", 'w');}//{$expr = new BitAndNode($expr, $op2.expr);} + )* + ; + +bitwiseXor returns [ExprTree expr]//[ExpressionNode expr] + : op1=bitwiseAnd {$expr = $op1.expr;} + ( '^' op2=bitwiseAnd {$expr = new ExprTree($expr, $op2.expr, "X", 'w');}//{$expr = new BitXorNode($expr, $op2.expr);} + )* + ; + +bitwiseOr returns [ExprTree expr]//[ExpressionNode expr] + : op1=bitwiseXor {$expr = $op1.expr;} + ( '|' op2=bitwiseXor {$expr = new ExprTree($expr, $op2.expr, "|", 'w');}//{$expr = new BitOrNode($expr, $op2.expr);} + )* + ; + +and returns [ExprTree expr] //[ExpressionNode expr] + : op1=bitwiseOr {$expr = $op1.expr;} + ( '&&' op2=bitwiseOr {$expr = new ExprTree($expr, $op2.expr, "&&", 'l');}//{$expr = new AndNode($expr, $op2.expr);} + // TODO: Temporarily set the type to 'l'. + )* + ; + +or returns [ExprTree expr]//[ExpressionNode expr] + : op1=and {$expr = $op1.expr;} + ( '||' op2=and {$expr = new ExprTree($expr, $op2.expr, "||", 'l');}//{$expr = new OrNode($expr, $op2.expr);} + // TODO: Temporarily set the type to 'l'. + )* + ; + +implication returns [ExprTree expr] //[ExpressionNode expr] + : op1=or {$expr = $op1.expr;}//{$expr = $op1.expr;} + ( '->' op2=or {$expr = new ExprTree($expr, $op2.expr, "->", 'l');}//{$expr = new ImplicationNode($expr, $op2.expr);} + )* + ; + +expression returns [ExprTree expr] // [ExpressionNode expr] + : op1=implication {$expr = $op1.expr;} + ('?' op2=expression ':' op3=expression + { + //$expr = new TernaryNode($expr, $op2.expr, $op3.expr); + // op1?op2:op3 == int(op1)*op2+int(~op1)*op3 + //$expr = new ExprTree($expr); + $expr = new ExprTree(new ExprTree(new ExprTree("int("+$op1.text + ")"), $op2.expr, "*", 'a'), + new ExprTree(new ExprTree("int(~("+$op1.text + "))"), $op3.expr, "*", 'a'), + "+", 'a'); + } + )? + ; + +// Boolean only expression +//boolTerm returns [ExpressionNode expr] +// : ID +// { +// if(ConstHashMap.containsKey($ID.text)){ +// $expr = new ConstNode($ID.text, ConstHashMap.get($ID.text)); +// } +// else if(VarHashSet.contains($ID.text)){ +// $expr = new platu.lpn.io.expression.VarNode($ID.text); +// } +// else{ +// System.err.println("error on line " + $ID.getLine() + ": " + $ID.text + " has not been declared"); +// System.exit(1); +// } +// } +// | LPAREN boolExpr RPAREN {$expr = $boolExpr.expr;} +// | INT {$expr = new ConstNode("name", Integer.parseInt($INT.text));} +// | TRUE {$expr = ONE;} +// | FALSE {$expr = ZERO;} +// ; +// +//boolNeg returns [ExpressionNode expr] +// : {Boolean neg = false;} +// ('!' +// { +// if(neg){ +// neg = false; +// } +// else{ +// neg = true; +// } +// } +// )* boolTerm +// { +// if(neg){ +// $expr = new NegNode($boolTerm.expr); +// } +// else{ +// $expr = $boolTerm.expr; +// } +// } +// ; +// +//boolRel returns [ExpressionNode expr] +// : op1=boolNeg {$expr = $op1.expr;} +// ( '<' op2=boolNeg {$expr = new LessNode($expr, $op2.expr);} +// | '<=' op2=boolNeg {$expr = new LessEqualNode($expr, $op2.expr);} +// | '>=' op2=boolNeg {$expr = new GreatEqualNode($expr, $op2.expr);} +// | '>' op2=boolNeg {$expr = new GreatNode($expr, $op2.expr);} +// )* +// ; +// +//boolEquiv returns [ExpressionNode expr] +// : op1=boolRel {$expr = $op1.expr;} +// ( '==' op2=boolRel {$expr = new EquivNode($expr, $op2.expr);} +// | '!=' op2=boolRel {$expr = new NotEquivNode($expr, $op2.expr);} +// )* +// ; +// +//boolAnd returns [ExpressionNode expr] +// : op1=boolEquiv {$expr = $op1.expr;} +// ( '&&' op2=boolEquiv {$expr = new AndNode($expr, $op2.expr);} +// )* +// ; +// +//boolOr returns [ExpressionNode expr] +// : op1=boolAnd {$expr = $op1.expr;} +// ( '||' op2=boolAnd {$expr = new OrNode($expr, $op2.expr);} +// )* +// ; +// +//boolExpr returns [ExpressionNode expr] +// : op1=boolOr {$expr = $op1.expr;} +// ('?' op2=boolExpr ':' op3=boolExpr +// { +// $expr = new TernaryNode($expr, $op2.expr, $op3.expr); +// } +// )? +// ; + +// Tokens +LPAREN: '('; +RPAREN: ')'; +QMARK: '?'; +COLON: ':'; +SEMICOLON: ';'; +PERIOD: '.'; +UNDERSCORE: '_'; +COMMA: ','; +QUOTE: '"'; + +// Reserved Words +MODULE: 'mod'; +NAME: 'name'; +INPUT: 'input'; +OUTPUT: 'output'; +INTERNAL: 'var'; +MARKING: 'marking'; +STATE_VECTOR: 'statevector'; +TRANSITION: 'transition'; +LABEL: 'label'; +PRESET: 'preset'; +POSTSET: 'postset'; +TRUE: 'true'; +FALSE: 'false'; + +// Arithmetic Operators +PLUS: '+'; +MINUS: '-'; +TIMES: '*'; +DIV: '/'; +MOD: '%'; +EQUALS: '='; + +// Comparison Operators +GREATER: '>'; +LESS: '<'; +GREATER_EQUAL: '>='; +LESS_EQUAL: '<='; +EQUIV: '=='; +NOT_EQUIV: '!='; + +// Logical Operators +NEGATION: '!'; +AND: '&&'; +OR: '||'; +IMPLICATION: '->'; + +// Bitwise Operators +BITWISE_NEGATION: '~'; +BITWISE_AND: '&'; +BITWISE_OR: '|'; +BITWISE_XOR: '^'; +BITWISE_LSHIFT: '<<'; +BITWISE_RSHIFT: '>>'; + +fragment LETTER: ('a'..'z' | 'A'..'Z'); +fragment DIGIT: '0'..'9'; +INT: '-'? DIGIT+; +ID: LETTER ((UNDERSCORE | PERIOD)? (LETTER | DIGIT))*; +WS: (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel = HIDDEN;}; +COMMENT: '//' .* ('\n' | '\r') {$channel = HIDDEN;}; +MULTILINECOMMENT: '/*' .* '*/' {$channel = HIDDEN;}; +XMLCOMMENT: ('<' '!' '-' '-') .* ('-' '-' '>') {$channel = HIDDEN;}; +IGNORE: '<' '?' .* '?' '>' {$channel = HIDDEN;}; + diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuGrammar.tokens b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuGrammar.tokens new file mode 100644 index 000000000..9360cd9b3 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuGrammar.tokens @@ -0,0 +1,104 @@ +T__57=57 +T__58=58 +T__59=59 +T__60=60 +T__61=61 +T__62=62 +T__63=63 +AND=4 +BITWISE_AND=5 +BITWISE_LSHIFT=6 +BITWISE_NEGATION=7 +BITWISE_OR=8 +BITWISE_RSHIFT=9 +BITWISE_XOR=10 +COLON=11 +COMMA=12 +COMMENT=13 +DIGIT=14 +DIV=15 +EQUALS=16 +EQUIV=17 +FALSE=18 +GREATER=19 +GREATER_EQUAL=20 +ID=21 +IGNORE=22 +IMPLICATION=23 +INPUT=24 +INT=25 +INTERNAL=26 +LABEL=27 +LESS=28 +LESS_EQUAL=29 +LETTER=30 +LPAREN=31 +MARKING=32 +MINUS=33 +MOD=34 +MODULE=35 +MULTILINECOMMENT=36 +NAME=37 +NEGATION=38 +NOT_EQUIV=39 +OR=40 +OUTPUT=41 +PERIOD=42 +PLUS=43 +POSTSET=44 +PRESET=45 +QMARK=46 +QUOTE=47 +RPAREN=48 +SEMICOLON=49 +STATE_VECTOR=50 +TIMES=51 +TRANSITION=52 +TRUE=53 +UNDERSCORE=54 +WS=55 +XMLCOMMENT=56 +'!'=38 +'!='=39 +'"'=47 +'&&'=4 +'&'=5 +'('=31 +')'=48 +'*'=51 +'+'=43 +','=12 +'-'=33 +'->'=23 +'.'=42 +'/'=15 +':'=11 +';'=49 +'<'=28 +'<<'=6 +'<='=29 +'='=16 +'=='=17 +'>'=19 +'>='=20 +'>>'=9 +'?'=46 +'['=57 +']'=58 +'^'=10 +'assert'=59 +'const'=60 +'inf'=61 +'inst'=62 +'label'=27 +'main'=63 +'marking'=32 +'mod'=35 +'name'=37 +'postset'=44 +'preset'=45 +'transition'=52 +'var'=26 +'|'=8 +'||'=40 +'~'=7 diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuGrammarLexer.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuGrammarLexer.java new file mode 100644 index 000000000..eb0ecacef --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuGrammarLexer.java @@ -0,0 +1,2514 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +// $ANTLR 3.4 /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g 2013-06-26 17:00:36 + + package edu.utah.ece.async.lema.verification.platu.platuLpn.io; + + +import org.antlr.runtime.*; +import java.util.Stack; +import java.util.List; +import java.util.ArrayList; + +@SuppressWarnings({"all", "warnings", "unchecked"}) +public class PlatuGrammarLexer extends Lexer { + public static final int EOF=-1; + public static final int T__57=57; + public static final int T__58=58; + public static final int T__59=59; + public static final int T__60=60; + public static final int T__61=61; + public static final int T__62=62; + public static final int T__63=63; + public static final int AND=4; + public static final int BITWISE_AND=5; + public static final int BITWISE_LSHIFT=6; + public static final int BITWISE_NEGATION=7; + public static final int BITWISE_OR=8; + public static final int BITWISE_RSHIFT=9; + public static final int BITWISE_XOR=10; + public static final int COLON=11; + public static final int COMMA=12; + public static final int COMMENT=13; + public static final int DIGIT=14; + public static final int DIV=15; + public static final int EQUALS=16; + public static final int EQUIV=17; + public static final int FALSE=18; + public static final int GREATER=19; + public static final int GREATER_EQUAL=20; + public static final int ID=21; + public static final int IGNORE=22; + public static final int IMPLICATION=23; + public static final int INPUT=24; + public static final int INT=25; + public static final int INTERNAL=26; + public static final int LABEL=27; + public static final int LESS=28; + public static final int LESS_EQUAL=29; + public static final int LETTER=30; + public static final int LPAREN=31; + public static final int MARKING=32; + public static final int MINUS=33; + public static final int MOD=34; + public static final int MODULE=35; + public static final int MULTILINECOMMENT=36; + public static final int NAME=37; + public static final int NEGATION=38; + public static final int NOT_EQUIV=39; + public static final int OR=40; + public static final int OUTPUT=41; + public static final int PERIOD=42; + public static final int PLUS=43; + public static final int POSTSET=44; + public static final int PRESET=45; + public static final int QMARK=46; + public static final int QUOTE=47; + public static final int RPAREN=48; + public static final int SEMICOLON=49; + public static final int STATE_VECTOR=50; + public static final int TIMES=51; + public static final int TRANSITION=52; + public static final int TRUE=53; + public static final int UNDERSCORE=54; + public static final int WS=55; + public static final int XMLCOMMENT=56; + + // delegates + // delegators + public Lexer[] getDelegates() { + return new Lexer[] {}; + } + + public PlatuGrammarLexer() {} + public PlatuGrammarLexer(CharStream input) { + this(input, new RecognizerSharedState()); + } + public PlatuGrammarLexer(CharStream input, RecognizerSharedState state) { + super(input,state); + } + public String getGrammarFileName() { return "/Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g"; } + + // $ANTLR start "T__57" + public final void mT__57() throws RecognitionException { + try { + int _type = T__57; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:11:7: ( '[' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:11:9: '[' + { + match('['); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "T__57" + + // $ANTLR start "T__58" + public final void mT__58() throws RecognitionException { + try { + int _type = T__58; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:12:7: ( ']' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:12:9: ']' + { + match(']'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "T__58" + + // $ANTLR start "T__59" + public final void mT__59() throws RecognitionException { + try { + int _type = T__59; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:13:7: ( 'assert' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:13:9: 'assert' + { + match("assert"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "T__59" + + // $ANTLR start "T__60" + public final void mT__60() throws RecognitionException { + try { + int _type = T__60; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:14:7: ( 'const' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:14:9: 'const' + { + match("const"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "T__60" + + // $ANTLR start "T__61" + public final void mT__61() throws RecognitionException { + try { + int _type = T__61; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:15:7: ( 'inf' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:15:9: 'inf' + { + match("inf"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "T__61" + + // $ANTLR start "T__62" + public final void mT__62() throws RecognitionException { + try { + int _type = T__62; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:16:7: ( 'inst' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:16:9: 'inst' + { + match("inst"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "T__62" + + // $ANTLR start "T__63" + public final void mT__63() throws RecognitionException { + try { + int _type = T__63; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:17:7: ( 'main' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:17:9: 'main' + { + match("main"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "T__63" + + // $ANTLR start "LPAREN" + public final void mLPAREN() throws RecognitionException { + try { + int _type = LPAREN; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1343:7: ( '(' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1343:9: '(' + { + match('('); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "LPAREN" + + // $ANTLR start "RPAREN" + public final void mRPAREN() throws RecognitionException { + try { + int _type = RPAREN; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1344:7: ( ')' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1344:9: ')' + { + match(')'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "RPAREN" + + // $ANTLR start "QMARK" + public final void mQMARK() throws RecognitionException { + try { + int _type = QMARK; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1345:6: ( '?' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1345:8: '?' + { + match('?'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "QMARK" + + // $ANTLR start "COLON" + public final void mCOLON() throws RecognitionException { + try { + int _type = COLON; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1346:6: ( ':' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1346:8: ':' + { + match(':'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "COLON" + + // $ANTLR start "SEMICOLON" + public final void mSEMICOLON() throws RecognitionException { + try { + int _type = SEMICOLON; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1347:10: ( ';' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1347:12: ';' + { + match(';'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "SEMICOLON" + + // $ANTLR start "PERIOD" + public final void mPERIOD() throws RecognitionException { + try { + int _type = PERIOD; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1348:7: ( '.' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1348:9: '.' + { + match('.'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "PERIOD" + + // $ANTLR start "UNDERSCORE" + public final void mUNDERSCORE() throws RecognitionException { + try { + int _type = UNDERSCORE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1349:11: ( '_' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1349:13: '_' + { + match('_'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "UNDERSCORE" + + // $ANTLR start "COMMA" + public final void mCOMMA() throws RecognitionException { + try { + int _type = COMMA; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1350:6: ( ',' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1350:8: ',' + { + match(','); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "COMMA" + + // $ANTLR start "QUOTE" + public final void mQUOTE() throws RecognitionException { + try { + int _type = QUOTE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1351:6: ( '\"' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1351:8: '\"' + { + match('\"'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "QUOTE" + + // $ANTLR start "MODULE" + public final void mMODULE() throws RecognitionException { + try { + int _type = MODULE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1354:7: ( 'mod' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1354:9: 'mod' + { + match("mod"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "MODULE" + + // $ANTLR start "NAME" + public final void mNAME() throws RecognitionException { + try { + int _type = NAME; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1355:5: ( 'name' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1355:7: 'name' + { + match("name"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "NAME" + + // $ANTLR start "INPUT" + public final void mINPUT() throws RecognitionException { + try { + int _type = INPUT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1356:6: ( 'input' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1356:8: 'input' + { + match("input"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "INPUT" + + // $ANTLR start "OUTPUT" + public final void mOUTPUT() throws RecognitionException { + try { + int _type = OUTPUT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1357:7: ( 'output' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1357:9: 'output' + { + match("output"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "OUTPUT" + + // $ANTLR start "INTERNAL" + public final void mINTERNAL() throws RecognitionException { + try { + int _type = INTERNAL; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1358:9: ( 'var' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1358:11: 'var' + { + match("var"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "INTERNAL" + + // $ANTLR start "MARKING" + public final void mMARKING() throws RecognitionException { + try { + int _type = MARKING; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1359:8: ( 'marking' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1359:10: 'marking' + { + match("marking"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "MARKING" + + // $ANTLR start "STATE_VECTOR" + public final void mSTATE_VECTOR() throws RecognitionException { + try { + int _type = STATE_VECTOR; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1360:13: ( 'statevector' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1360:15: 'statevector' + { + match("statevector"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "STATE_VECTOR" + + // $ANTLR start "TRANSITION" + public final void mTRANSITION() throws RecognitionException { + try { + int _type = TRANSITION; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1361:11: ( 'transition' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1361:13: 'transition' + { + match("transition"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "TRANSITION" + + // $ANTLR start "LABEL" + public final void mLABEL() throws RecognitionException { + try { + int _type = LABEL; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1362:6: ( 'label' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1362:8: 'label' + { + match("label"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "LABEL" + + // $ANTLR start "PRESET" + public final void mPRESET() throws RecognitionException { + try { + int _type = PRESET; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1363:7: ( 'preset' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1363:9: 'preset' + { + match("preset"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "PRESET" + + // $ANTLR start "POSTSET" + public final void mPOSTSET() throws RecognitionException { + try { + int _type = POSTSET; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1364:8: ( 'postset' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1364:10: 'postset' + { + match("postset"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "POSTSET" + + // $ANTLR start "TRUE" + public final void mTRUE() throws RecognitionException { + try { + int _type = TRUE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1365:5: ( 'true' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1365:7: 'true' + { + match("true"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "TRUE" + + // $ANTLR start "FALSE" + public final void mFALSE() throws RecognitionException { + try { + int _type = FALSE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1366:6: ( 'false' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1366:8: 'false' + { + match("false"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "FALSE" + + // $ANTLR start "PLUS" + public final void mPLUS() throws RecognitionException { + try { + int _type = PLUS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1369:5: ( '+' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1369:7: '+' + { + match('+'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "PLUS" + + // $ANTLR start "MINUS" + public final void mMINUS() throws RecognitionException { + try { + int _type = MINUS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1370:6: ( '-' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1370:8: '-' + { + match('-'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "MINUS" + + // $ANTLR start "TIMES" + public final void mTIMES() throws RecognitionException { + try { + int _type = TIMES; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1371:6: ( '*' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1371:8: '*' + { + match('*'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "TIMES" + + // $ANTLR start "DIV" + public final void mDIV() throws RecognitionException { + try { + int _type = DIV; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1372:4: ( '/' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1372:6: '/' + { + match('/'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "DIV" + + // $ANTLR start "MOD" + public final void mMOD() throws RecognitionException { + try { + int _type = MOD; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1373:4: ( '%' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1373:6: '%' + { + match('%'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "MOD" + + // $ANTLR start "EQUALS" + public final void mEQUALS() throws RecognitionException { + try { + int _type = EQUALS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1374:7: ( '=' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1374:9: '=' + { + match('='); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "EQUALS" + + // $ANTLR start "GREATER" + public final void mGREATER() throws RecognitionException { + try { + int _type = GREATER; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1377:8: ( '>' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1377:10: '>' + { + match('>'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "GREATER" + + // $ANTLR start "LESS" + public final void mLESS() throws RecognitionException { + try { + int _type = LESS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1378:5: ( '<' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1378:7: '<' + { + match('<'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "LESS" + + // $ANTLR start "GREATER_EQUAL" + public final void mGREATER_EQUAL() throws RecognitionException { + try { + int _type = GREATER_EQUAL; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1379:14: ( '>=' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1379:16: '>=' + { + match(">="); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "GREATER_EQUAL" + + // $ANTLR start "LESS_EQUAL" + public final void mLESS_EQUAL() throws RecognitionException { + try { + int _type = LESS_EQUAL; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1380:11: ( '<=' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1380:13: '<=' + { + match("<="); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "LESS_EQUAL" + + // $ANTLR start "EQUIV" + public final void mEQUIV() throws RecognitionException { + try { + int _type = EQUIV; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1381:6: ( '==' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1381:8: '==' + { + match("=="); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "EQUIV" + + // $ANTLR start "NOT_EQUIV" + public final void mNOT_EQUIV() throws RecognitionException { + try { + int _type = NOT_EQUIV; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1382:10: ( '!=' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1382:12: '!=' + { + match("!="); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "NOT_EQUIV" + + // $ANTLR start "NEGATION" + public final void mNEGATION() throws RecognitionException { + try { + int _type = NEGATION; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1385:9: ( '!' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1385:11: '!' + { + match('!'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "NEGATION" + + // $ANTLR start "AND" + public final void mAND() throws RecognitionException { + try { + int _type = AND; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1386:4: ( '&&' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1386:6: '&&' + { + match("&&"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "AND" + + // $ANTLR start "OR" + public final void mOR() throws RecognitionException { + try { + int _type = OR; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1387:3: ( '||' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1387:5: '||' + { + match("||"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "OR" + + // $ANTLR start "IMPLICATION" + public final void mIMPLICATION() throws RecognitionException { + try { + int _type = IMPLICATION; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1388:12: ( '->' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1388:14: '->' + { + match("->"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "IMPLICATION" + + // $ANTLR start "BITWISE_NEGATION" + public final void mBITWISE_NEGATION() throws RecognitionException { + try { + int _type = BITWISE_NEGATION; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1391:17: ( '~' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1391:19: '~' + { + match('~'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "BITWISE_NEGATION" + + // $ANTLR start "BITWISE_AND" + public final void mBITWISE_AND() throws RecognitionException { + try { + int _type = BITWISE_AND; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1392:12: ( '&' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1392:14: '&' + { + match('&'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "BITWISE_AND" + + // $ANTLR start "BITWISE_OR" + public final void mBITWISE_OR() throws RecognitionException { + try { + int _type = BITWISE_OR; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1393:11: ( '|' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1393:13: '|' + { + match('|'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "BITWISE_OR" + + // $ANTLR start "BITWISE_XOR" + public final void mBITWISE_XOR() throws RecognitionException { + try { + int _type = BITWISE_XOR; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1394:12: ( '^' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1394:14: '^' + { + match('^'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "BITWISE_XOR" + + // $ANTLR start "BITWISE_LSHIFT" + public final void mBITWISE_LSHIFT() throws RecognitionException { + try { + int _type = BITWISE_LSHIFT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1395:15: ( '<<' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1395:17: '<<' + { + match("<<"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "BITWISE_LSHIFT" + + // $ANTLR start "BITWISE_RSHIFT" + public final void mBITWISE_RSHIFT() throws RecognitionException { + try { + int _type = BITWISE_RSHIFT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1396:15: ( '>>' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1396:17: '>>' + { + match(">>"); + + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "BITWISE_RSHIFT" + + // $ANTLR start "LETTER" + public final void mLETTER() throws RecognitionException { + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1398:16: ( ( 'a' .. 'z' | 'A' .. 'Z' ) ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g: + { + if ( (input.LA(1) >= 'A' && input.LA(1) <= 'Z')||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + + + } + + + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "LETTER" + + // $ANTLR start "DIGIT" + public final void mDIGIT() throws RecognitionException { + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1399:15: ( '0' .. '9' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g: + { + if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + + + } + + + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "DIGIT" + + // $ANTLR start "INT" + public final void mINT() throws RecognitionException { + try { + int _type = INT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1400:4: ( ( '-' )? ( DIGIT )+ ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1400:6: ( '-' )? ( DIGIT )+ + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1400:6: ( '-' )? + int alt1=2; + int LA1_0 = input.LA(1); + + if ( (LA1_0=='-') ) { + alt1=1; + } + switch (alt1) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1400:6: '-' + { + match('-'); + + } + break; + + } + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1400:11: ( DIGIT )+ + int cnt2=0; + loop2: + do { + int alt2=2; + int LA2_0 = input.LA(1); + + if ( ((LA2_0 >= '0' && LA2_0 <= '9')) ) { + alt2=1; + } + + + switch (alt2) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g: + { + if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + + + } + break; + + default : + if ( cnt2 >= 1 ) break loop2; + EarlyExitException eee = + new EarlyExitException(2, input); + throw eee; + } + cnt2++; + } while (true); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "INT" + + // $ANTLR start "ID" + public final void mID() throws RecognitionException { + try { + int _type = ID; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1401:3: ( LETTER ( ( UNDERSCORE | PERIOD )? ( LETTER | DIGIT ) )* ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1401:5: LETTER ( ( UNDERSCORE | PERIOD )? ( LETTER | DIGIT ) )* + { + mLETTER(); + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1401:12: ( ( UNDERSCORE | PERIOD )? ( LETTER | DIGIT ) )* + loop4: + do { + int alt4=2; + int LA4_0 = input.LA(1); + + if ( (LA4_0=='.'||(LA4_0 >= '0' && LA4_0 <= '9')||(LA4_0 >= 'A' && LA4_0 <= 'Z')||LA4_0=='_'||(LA4_0 >= 'a' && LA4_0 <= 'z')) ) { + alt4=1; + } + + + switch (alt4) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1401:13: ( UNDERSCORE | PERIOD )? ( LETTER | DIGIT ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1401:13: ( UNDERSCORE | PERIOD )? + int alt3=2; + int LA3_0 = input.LA(1); + + if ( (LA3_0=='.'||LA3_0=='_') ) { + alt3=1; + } + switch (alt3) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g: + { + if ( input.LA(1)=='.'||input.LA(1)=='_' ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + + + } + break; + + } + + + if ( (input.LA(1) >= '0' && input.LA(1) <= '9')||(input.LA(1) >= 'A' && input.LA(1) <= 'Z')||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + + + } + break; + + default : + break loop4; + } + } while (true); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "ID" + + // $ANTLR start "WS" + public final void mWS() throws RecognitionException { + try { + int _type = WS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1402:3: ( ( ' ' | '\\t' | '\\n' | '\\r' | '\\f' )+ ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1402:5: ( ' ' | '\\t' | '\\n' | '\\r' | '\\f' )+ + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1402:5: ( ' ' | '\\t' | '\\n' | '\\r' | '\\f' )+ + int cnt5=0; + loop5: + do { + int alt5=2; + int LA5_0 = input.LA(1); + + if ( ((LA5_0 >= '\t' && LA5_0 <= '\n')||(LA5_0 >= '\f' && LA5_0 <= '\r')||LA5_0==' ') ) { + alt5=1; + } + + + switch (alt5) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g: + { + if ( (input.LA(1) >= '\t' && input.LA(1) <= '\n')||(input.LA(1) >= '\f' && input.LA(1) <= '\r')||input.LA(1)==' ' ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + + + } + break; + + default : + if ( cnt5 >= 1 ) break loop5; + EarlyExitException eee = + new EarlyExitException(5, input); + throw eee; + } + cnt5++; + } while (true); + + + _channel = HIDDEN; + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "WS" + + // $ANTLR start "COMMENT" + public final void mCOMMENT() throws RecognitionException { + try { + int _type = COMMENT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1403:8: ( '//' ( . )* ( '\\n' | '\\r' ) ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1403:10: '//' ( . )* ( '\\n' | '\\r' ) + { + match("//"); + + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1403:15: ( . )* + loop6: + do { + int alt6=2; + int LA6_0 = input.LA(1); + + if ( (LA6_0=='\n'||LA6_0=='\r') ) { + alt6=2; + } + else if ( ((LA6_0 >= '\u0000' && LA6_0 <= '\t')||(LA6_0 >= '\u000B' && LA6_0 <= '\f')||(LA6_0 >= '\u000E' && LA6_0 <= '\uFFFF')) ) { + alt6=1; + } + + + switch (alt6) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1403:15: . + { + matchAny(); + + } + break; + + default : + break loop6; + } + } while (true); + + + if ( input.LA(1)=='\n'||input.LA(1)=='\r' ) { + input.consume(); + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse; + } + + + _channel = HIDDEN; + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "COMMENT" + + // $ANTLR start "MULTILINECOMMENT" + public final void mMULTILINECOMMENT() throws RecognitionException { + try { + int _type = MULTILINECOMMENT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1404:17: ( '/*' ( . )* '*/' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1404:19: '/*' ( . )* '*/' + { + match("/*"); + + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1404:24: ( . )* + loop7: + do { + int alt7=2; + int LA7_0 = input.LA(1); + + if ( (LA7_0=='*') ) { + int LA7_1 = input.LA(2); + + if ( (LA7_1=='/') ) { + alt7=2; + } + else if ( ((LA7_1 >= '\u0000' && LA7_1 <= '.')||(LA7_1 >= '0' && LA7_1 <= '\uFFFF')) ) { + alt7=1; + } + + + } + else if ( ((LA7_0 >= '\u0000' && LA7_0 <= ')')||(LA7_0 >= '+' && LA7_0 <= '\uFFFF')) ) { + alt7=1; + } + + + switch (alt7) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1404:24: . + { + matchAny(); + + } + break; + + default : + break loop7; + } + } while (true); + + + match("*/"); + + + + _channel = HIDDEN; + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "MULTILINECOMMENT" + + // $ANTLR start "XMLCOMMENT" + public final void mXMLCOMMENT() throws RecognitionException { + try { + int _type = XMLCOMMENT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1405:11: ( ( '<' '!' '-' '-' ) ( . )* ( '-' '-' '>' ) ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1405:13: ( '<' '!' '-' '-' ) ( . )* ( '-' '-' '>' ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1405:13: ( '<' '!' '-' '-' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1405:14: '<' '!' '-' '-' + { + match('<'); + + match('!'); + + match('-'); + + match('-'); + + } + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1405:31: ( . )* + loop8: + do { + int alt8=2; + int LA8_0 = input.LA(1); + + if ( (LA8_0=='-') ) { + int LA8_1 = input.LA(2); + + if ( (LA8_1=='-') ) { + int LA8_3 = input.LA(3); + + if ( (LA8_3=='>') ) { + alt8=2; + } + else if ( ((LA8_3 >= '\u0000' && LA8_3 <= '=')||(LA8_3 >= '?' && LA8_3 <= '\uFFFF')) ) { + alt8=1; + } + + + } + else if ( ((LA8_1 >= '\u0000' && LA8_1 <= ',')||(LA8_1 >= '.' && LA8_1 <= '\uFFFF')) ) { + alt8=1; + } + + + } + else if ( ((LA8_0 >= '\u0000' && LA8_0 <= ',')||(LA8_0 >= '.' && LA8_0 <= '\uFFFF')) ) { + alt8=1; + } + + + switch (alt8) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1405:31: . + { + matchAny(); + + } + break; + + default : + break loop8; + } + } while (true); + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1405:34: ( '-' '-' '>' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1405:35: '-' '-' '>' + { + match('-'); + + match('-'); + + match('>'); + + } + + + _channel = HIDDEN; + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "XMLCOMMENT" + + // $ANTLR start "IGNORE" + public final void mIGNORE() throws RecognitionException { + try { + int _type = IGNORE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1406:7: ( '<' '?' ( . )* '?' '>' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1406:9: '<' '?' ( . )* '?' '>' + { + match('<'); + + match('?'); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1406:17: ( . )* + loop9: + do { + int alt9=2; + int LA9_0 = input.LA(1); + + if ( (LA9_0=='?') ) { + int LA9_1 = input.LA(2); + + if ( (LA9_1=='>') ) { + alt9=2; + } + else if ( ((LA9_1 >= '\u0000' && LA9_1 <= '=')||(LA9_1 >= '?' && LA9_1 <= '\uFFFF')) ) { + alt9=1; + } + + + } + else if ( ((LA9_0 >= '\u0000' && LA9_0 <= '>')||(LA9_0 >= '@' && LA9_0 <= '\uFFFF')) ) { + alt9=1; + } + + + switch (alt9) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1406:17: . + { + matchAny(); + + } + break; + + default : + break loop9; + } + } while (true); + + + match('?'); + + match('>'); + + _channel = HIDDEN; + + } + + state.type = _type; + state.channel = _channel; + } + finally { + // do for sure before leaving + } + } + // $ANTLR end "IGNORE" + + public void mTokens() throws RecognitionException { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:8: ( T__57 | T__58 | T__59 | T__60 | T__61 | T__62 | T__63 | LPAREN | RPAREN | QMARK | COLON | SEMICOLON | PERIOD | UNDERSCORE | COMMA | QUOTE | MODULE | NAME | INPUT | OUTPUT | INTERNAL | MARKING | STATE_VECTOR | TRANSITION | LABEL | PRESET | POSTSET | TRUE | FALSE | PLUS | MINUS | TIMES | DIV | MOD | EQUALS | GREATER | LESS | GREATER_EQUAL | LESS_EQUAL | EQUIV | NOT_EQUIV | NEGATION | AND | OR | IMPLICATION | BITWISE_NEGATION | BITWISE_AND | BITWISE_OR | BITWISE_XOR | BITWISE_LSHIFT | BITWISE_RSHIFT | INT | ID | WS | COMMENT | MULTILINECOMMENT | XMLCOMMENT | IGNORE ) + int alt10=58; + alt10 = dfa10.predict(input); + switch (alt10) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:10: T__57 + { + mT__57(); + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:16: T__58 + { + mT__58(); + + + } + break; + case 3 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:22: T__59 + { + mT__59(); + + + } + break; + case 4 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:28: T__60 + { + mT__60(); + + + } + break; + case 5 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:34: T__61 + { + mT__61(); + + + } + break; + case 6 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:40: T__62 + { + mT__62(); + + + } + break; + case 7 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:46: T__63 + { + mT__63(); + + + } + break; + case 8 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:52: LPAREN + { + mLPAREN(); + + + } + break; + case 9 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:59: RPAREN + { + mRPAREN(); + + + } + break; + case 10 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:66: QMARK + { + mQMARK(); + + + } + break; + case 11 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:72: COLON + { + mCOLON(); + + + } + break; + case 12 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:78: SEMICOLON + { + mSEMICOLON(); + + + } + break; + case 13 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:88: PERIOD + { + mPERIOD(); + + + } + break; + case 14 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:95: UNDERSCORE + { + mUNDERSCORE(); + + + } + break; + case 15 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:106: COMMA + { + mCOMMA(); + + + } + break; + case 16 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:112: QUOTE + { + mQUOTE(); + + + } + break; + case 17 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:118: MODULE + { + mMODULE(); + + + } + break; + case 18 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:125: NAME + { + mNAME(); + + + } + break; + case 19 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:130: INPUT + { + mINPUT(); + + + } + break; + case 20 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:136: OUTPUT + { + mOUTPUT(); + + + } + break; + case 21 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:143: INTERNAL + { + mINTERNAL(); + + + } + break; + case 22 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:152: MARKING + { + mMARKING(); + + + } + break; + case 23 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:160: STATE_VECTOR + { + mSTATE_VECTOR(); + + + } + break; + case 24 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:173: TRANSITION + { + mTRANSITION(); + + + } + break; + case 25 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:184: LABEL + { + mLABEL(); + + + } + break; + case 26 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:190: PRESET + { + mPRESET(); + + + } + break; + case 27 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:197: POSTSET + { + mPOSTSET(); + + + } + break; + case 28 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:205: TRUE + { + mTRUE(); + + + } + break; + case 29 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:210: FALSE + { + mFALSE(); + + + } + break; + case 30 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:216: PLUS + { + mPLUS(); + + + } + break; + case 31 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:221: MINUS + { + mMINUS(); + + + } + break; + case 32 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:227: TIMES + { + mTIMES(); + + + } + break; + case 33 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:233: DIV + { + mDIV(); + + + } + break; + case 34 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:237: MOD + { + mMOD(); + + + } + break; + case 35 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:241: EQUALS + { + mEQUALS(); + + + } + break; + case 36 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:248: GREATER + { + mGREATER(); + + + } + break; + case 37 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:256: LESS + { + mLESS(); + + + } + break; + case 38 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:261: GREATER_EQUAL + { + mGREATER_EQUAL(); + + + } + break; + case 39 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:275: LESS_EQUAL + { + mLESS_EQUAL(); + + + } + break; + case 40 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:286: EQUIV + { + mEQUIV(); + + + } + break; + case 41 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:292: NOT_EQUIV + { + mNOT_EQUIV(); + + + } + break; + case 42 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:302: NEGATION + { + mNEGATION(); + + + } + break; + case 43 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:311: AND + { + mAND(); + + + } + break; + case 44 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:315: OR + { + mOR(); + + + } + break; + case 45 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:318: IMPLICATION + { + mIMPLICATION(); + + + } + break; + case 46 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:330: BITWISE_NEGATION + { + mBITWISE_NEGATION(); + + + } + break; + case 47 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:347: BITWISE_AND + { + mBITWISE_AND(); + + + } + break; + case 48 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:359: BITWISE_OR + { + mBITWISE_OR(); + + + } + break; + case 49 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:370: BITWISE_XOR + { + mBITWISE_XOR(); + + + } + break; + case 50 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:382: BITWISE_LSHIFT + { + mBITWISE_LSHIFT(); + + + } + break; + case 51 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:397: BITWISE_RSHIFT + { + mBITWISE_RSHIFT(); + + + } + break; + case 52 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:412: INT + { + mINT(); + + + } + break; + case 53 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:416: ID + { + mID(); + + + } + break; + case 54 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:419: WS + { + mWS(); + + + } + break; + case 55 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:422: COMMENT + { + mCOMMENT(); + + + } + break; + case 56 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:430: MULTILINECOMMENT + { + mMULTILINECOMMENT(); + + + } + break; + case 57 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:447: XMLCOMMENT + { + mXMLCOMMENT(); + + + } + break; + case 58 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1:458: IGNORE + { + mIGNORE(); + + + } + break; + + } + + } + + + protected DFA10 dfa10 = new DFA10(this); + static final String DFA10_eotS = + "\3\uffff\4\46\11\uffff\10\46\1\uffff\1\67\1\uffff\1\72\1\uffff\1"+ + "\74\1\77\1\104\1\106\1\110\1\112\5\uffff\16\46\25\uffff\2\46\1\137"+ + "\4\46\1\144\2\46\1\147\11\46\1\uffff\1\161\1\46\1\163\1\46\1\uffff"+ + "\1\165\1\46\1\uffff\2\46\1\171\5\46\1\177\1\uffff\1\u0080\1\uffff"+ + "\1\46\1\uffff\3\46\1\uffff\1\u0085\2\46\1\u0088\1\u0089\2\uffff"+ + "\1\46\1\u008b\2\46\1\uffff\1\u008e\1\46\2\uffff\1\u0090\1\uffff"+ + "\2\46\1\uffff\1\u0093\1\uffff\2\46\1\uffff\3\46\1\u0099\1\u009a"+ + "\2\uffff"; + static final String DFA10_eofS = + "\u009b\uffff"; + static final String DFA10_minS = + "\1\11\2\uffff\1\163\1\157\1\156\1\141\11\uffff\1\141\1\165\1\141"+ + "\1\164\1\162\1\141\1\157\1\141\1\uffff\1\60\1\uffff\1\52\1\uffff"+ + "\2\75\1\41\1\75\1\46\1\174\5\uffff\1\163\1\156\1\146\1\151\1\144"+ + "\1\155\1\164\1\162\2\141\1\142\1\145\1\163\1\154\25\uffff\1\145"+ + "\1\163\1\56\1\164\1\165\1\156\1\153\1\56\1\145\1\160\1\56\1\164"+ + "\1\156\2\145\1\163\1\164\1\163\1\162\1\164\1\uffff\1\56\1\164\1"+ + "\56\1\151\1\uffff\1\56\1\165\1\uffff\1\145\1\163\1\56\1\154\1\145"+ + "\1\163\1\145\1\164\1\56\1\uffff\1\56\1\uffff\1\156\1\uffff\1\164"+ + "\1\166\1\151\1\uffff\1\56\1\164\1\145\2\56\2\uffff\1\147\1\56\1"+ + "\145\1\164\1\uffff\1\56\1\164\2\uffff\1\56\1\uffff\1\143\1\151\1"+ + "\uffff\1\56\1\uffff\1\164\1\157\1\uffff\1\157\1\156\1\162\2\56\2"+ + "\uffff"; + static final String DFA10_maxS = + "\1\176\2\uffff\1\163\1\157\1\156\1\157\11\uffff\1\141\1\165\1\141"+ + "\1\164\1\162\1\141\1\162\1\141\1\uffff\1\76\1\uffff\1\57\1\uffff"+ + "\1\75\1\76\1\77\1\75\1\46\1\174\5\uffff\1\163\1\156\1\163\1\162"+ + "\1\144\1\155\1\164\1\162\1\141\1\165\1\142\1\145\1\163\1\154\25"+ + "\uffff\1\145\1\163\1\172\1\164\1\165\1\156\1\153\1\172\1\145\1\160"+ + "\1\172\1\164\1\156\2\145\1\163\1\164\1\163\1\162\1\164\1\uffff\1"+ + "\172\1\164\1\172\1\151\1\uffff\1\172\1\165\1\uffff\1\145\1\163\1"+ + "\172\1\154\1\145\1\163\1\145\1\164\1\172\1\uffff\1\172\1\uffff\1"+ + "\156\1\uffff\1\164\1\166\1\151\1\uffff\1\172\1\164\1\145\2\172\2"+ + "\uffff\1\147\1\172\1\145\1\164\1\uffff\1\172\1\164\2\uffff\1\172"+ + "\1\uffff\1\143\1\151\1\uffff\1\172\1\uffff\1\164\1\157\1\uffff\1"+ + "\157\1\156\1\162\2\172\2\uffff"; + static final String DFA10_acceptS = + "\1\uffff\1\1\1\2\4\uffff\1\10\1\11\1\12\1\13\1\14\1\15\1\16\1\17"+ + "\1\20\10\uffff\1\36\1\uffff\1\40\1\uffff\1\42\6\uffff\1\56\1\61"+ + "\1\64\1\65\1\66\16\uffff\1\55\1\37\1\67\1\70\1\41\1\50\1\43\1\46"+ + "\1\63\1\44\1\47\1\62\1\71\1\72\1\45\1\51\1\52\1\53\1\57\1\54\1\60"+ + "\24\uffff\1\5\4\uffff\1\21\2\uffff\1\25\11\uffff\1\6\1\uffff\1\7"+ + "\1\uffff\1\22\3\uffff\1\34\5\uffff\1\4\1\23\4\uffff\1\31\2\uffff"+ + "\1\35\1\3\1\uffff\1\24\2\uffff\1\32\1\uffff\1\26\2\uffff\1\33\5"+ + "\uffff\1\30\1\27"; + static final String DFA10_specialS = + "\u009b\uffff}>"; + static final String[] DFA10_transitionS = { + "\2\47\1\uffff\2\47\22\uffff\1\47\1\40\1\17\2\uffff\1\34\1\41"+ + "\1\uffff\1\7\1\10\1\32\1\30\1\16\1\31\1\14\1\33\12\45\1\12\1"+ + "\13\1\37\1\35\1\36\1\11\1\uffff\32\46\1\1\1\uffff\1\2\1\44\1"+ + "\15\1\uffff\1\3\1\46\1\4\2\46\1\27\2\46\1\5\2\46\1\25\1\6\1"+ + "\20\1\21\1\26\2\46\1\23\1\24\1\46\1\22\4\46\1\uffff\1\42\1\uffff"+ + "\1\43", + "", + "", + "\1\50", + "\1\51", + "\1\52", + "\1\53\15\uffff\1\54", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "\1\55", + "\1\56", + "\1\57", + "\1\60", + "\1\61", + "\1\62", + "\1\64\2\uffff\1\63", + "\1\65", + "", + "\12\45\4\uffff\1\66", + "", + "\1\71\4\uffff\1\70", + "", + "\1\73", + "\1\75\1\76", + "\1\102\32\uffff\1\101\1\100\1\uffff\1\103", + "\1\105", + "\1\107", + "\1\111", + "", + "", + "", + "", + "", + "\1\113", + "\1\114", + "\1\115\11\uffff\1\117\2\uffff\1\116", + "\1\120\10\uffff\1\121", + "\1\122", + "\1\123", + "\1\124", + "\1\125", + "\1\126", + "\1\127\23\uffff\1\130", + "\1\131", + "\1\132", + "\1\133", + "\1\134", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "\1\135", + "\1\136", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "\1\140", + "\1\141", + "\1\142", + "\1\143", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "\1\145", + "\1\146", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "\1\150", + "\1\151", + "\1\152", + "\1\153", + "\1\154", + "\1\155", + "\1\156", + "\1\157", + "\1\160", + "", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "\1\162", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "\1\164", + "", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "\1\166", + "", + "\1\167", + "\1\170", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "\1\172", + "\1\173", + "\1\174", + "\1\175", + "\1\176", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "", + "\1\u0081", + "", + "\1\u0082", + "\1\u0083", + "\1\u0084", + "", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "\1\u0086", + "\1\u0087", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "", + "", + "\1\u008a", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "\1\u008c", + "\1\u008d", + "", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "\1\u008f", + "", + "", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "", + "\1\u0091", + "\1\u0092", + "", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "", + "\1\u0094", + "\1\u0095", + "", + "\1\u0096", + "\1\u0097", + "\1\u0098", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "\1\46\1\uffff\12\46\7\uffff\32\46\4\uffff\1\46\1\uffff\32\46", + "", + "" + }; + + static final short[] DFA10_eot = DFA.unpackEncodedString(DFA10_eotS); + static final short[] DFA10_eof = DFA.unpackEncodedString(DFA10_eofS); + static final char[] DFA10_min = DFA.unpackEncodedStringToUnsignedChars(DFA10_minS); + static final char[] DFA10_max = DFA.unpackEncodedStringToUnsignedChars(DFA10_maxS); + static final short[] DFA10_accept = DFA.unpackEncodedString(DFA10_acceptS); + static final short[] DFA10_special = DFA.unpackEncodedString(DFA10_specialS); + static final short[][] DFA10_transition; + + static { + int numStates = DFA10_transitionS.length; + DFA10_transition = new short[numStates][]; + for (int i=0; i + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +// $ANTLR 3.4 /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g 2013-06-26 17:00:34 + + package edu.utah.ece.async.lema.verification.platu.platuLpn.io; + + import java.util.Map.Entry; + import java.util.HashMap; + import java.util.LinkedList; + import java.util.HashSet; + import java.util.Set; + import java.util.Arrays; + +import org.antlr.runtime.*; + +import edu.utah.ece.async.lema.verification.lpn.ExprTree; +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Place; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.lpn.Variable; +import edu.utah.ece.async.lema.verification.platu.expression.*; +import edu.utah.ece.async.lema.verification.platu.platuLpn.DualHashMap; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LPNTran; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LpnTranList; +import edu.utah.ece.async.lema.verification.platu.platuLpn.VarExpr; +import edu.utah.ece.async.lema.verification.platu.platuLpn.VarExprList; +import edu.utah.ece.async.lema.verification.platu.platuLpn.VarSet; +import edu.utah.ece.async.lema.verification.platu.project.Project; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +import java.util.Stack; +import java.util.List; +import java.util.ArrayList; + +@SuppressWarnings({"all", "warnings", "unchecked"}) +public class PlatuGrammarParser extends Parser { + public static final String[] tokenNames = new String[] { + "", "", "", "", "AND", "BITWISE_AND", "BITWISE_LSHIFT", "BITWISE_NEGATION", "BITWISE_OR", "BITWISE_RSHIFT", "BITWISE_XOR", "COLON", "COMMA", "COMMENT", "DIGIT", "DIV", "EQUALS", "EQUIV", "FALSE", "GREATER", "GREATER_EQUAL", "ID", "IGNORE", "IMPLICATION", "INPUT", "INT", "INTERNAL", "LABEL", "LESS", "LESS_EQUAL", "LETTER", "LPAREN", "MARKING", "MINUS", "MOD", "MODULE", "MULTILINECOMMENT", "NAME", "NEGATION", "NOT_EQUIV", "OR", "OUTPUT", "PERIOD", "PLUS", "POSTSET", "PRESET", "QMARK", "QUOTE", "RPAREN", "SEMICOLON", "STATE_VECTOR", "TIMES", "TRANSITION", "TRUE", "UNDERSCORE", "WS", "XMLCOMMENT", "'['", "']'", "'assert'", "'const'", "'inf'", "'inst'", "'main'" + }; + + public static final int EOF=-1; + public static final int T__57=57; + public static final int T__58=58; + public static final int T__59=59; + public static final int T__60=60; + public static final int T__61=61; + public static final int T__62=62; + public static final int T__63=63; + public static final int AND=4; + public static final int BITWISE_AND=5; + public static final int BITWISE_LSHIFT=6; + public static final int BITWISE_NEGATION=7; + public static final int BITWISE_OR=8; + public static final int BITWISE_RSHIFT=9; + public static final int BITWISE_XOR=10; + public static final int COLON=11; + public static final int COMMA=12; + public static final int COMMENT=13; + public static final int DIGIT=14; + public static final int DIV=15; + public static final int EQUALS=16; + public static final int EQUIV=17; + public static final int FALSE=18; + public static final int GREATER=19; + public static final int GREATER_EQUAL=20; + public static final int ID=21; + public static final int IGNORE=22; + public static final int IMPLICATION=23; + public static final int INPUT=24; + public static final int INT=25; + public static final int INTERNAL=26; + public static final int LABEL=27; + public static final int LESS=28; + public static final int LESS_EQUAL=29; + public static final int LETTER=30; + public static final int LPAREN=31; + public static final int MARKING=32; + public static final int MINUS=33; + public static final int MOD=34; + public static final int MODULE=35; + public static final int MULTILINECOMMENT=36; + public static final int NAME=37; + public static final int NEGATION=38; + public static final int NOT_EQUIV=39; + public static final int OR=40; + public static final int OUTPUT=41; + public static final int PERIOD=42; + public static final int PLUS=43; + public static final int POSTSET=44; + public static final int PRESET=45; + public static final int QMARK=46; + public static final int QUOTE=47; + public static final int RPAREN=48; + public static final int SEMICOLON=49; + public static final int STATE_VECTOR=50; + public static final int TIMES=51; + public static final int TRANSITION=52; + public static final int TRUE=53; + public static final int UNDERSCORE=54; + public static final int WS=55; + public static final int XMLCOMMENT=56; + + // delegates + public Parser[] getDelegates() { + return new Parser[] {}; + } + + // delegators + + + public PlatuGrammarParser(TokenStream input) { + this(input, new RecognizerSharedState()); + } + public PlatuGrammarParser(TokenStream input, RecognizerSharedState state) { + super(input, state); + } + + public String[] getTokenNames() { return PlatuGrammarParser.tokenNames; } + public String getGrammarFileName() { return "/Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g"; } + + + // static variables + static private int INFINITY = Integer.MAX_VALUE; + static private boolean main = false; + // static private ExprTree ZERO = new ExprTree("false"); // constant false node + // static private ExprTree ONE = new ExprTree("true"); // constant true node + static private HashMap LpnMap = new HashMap(); // all modules parsed, keyed by module name + static private HashMap GlobalVarHashMap = new HashMap(); // global variables and associated values + static private HashMap GlobalOutputMap = new HashMap(); // maps potential output variables to associated lpn + static private HashMap GlobalInterfaceMap = new HashMap(); // maps variables to initial values, input have null value until associated output is found + static private HashMap> GlobalInputMap = new HashMap>(); // maps input variables to associated lpn + static private HashMap> GlobalTranMap = new HashMap>(); // maps potential output variables to lpn transitions which affect it + static private HashMap GlobalVarNodeMap = new HashMap(); // maps global variable name to variable object + //static private ExpressionNode ZERO = new ConstNode("FALSE", 0); + //static private ExpressionNode ONE = new ConstNode("TRUE", 1); // constant true node + //static private Expression TrueExpr = new Expression(ONE); // constant true expression + // static private HashMap LpnMap = new HashMap(); // all modules parsed, keyed by module name + // static private HashMap GlobalVarHashMap = new HashMap(); // global variables and associated values + // static private HashMap GlobalOutputMap = new HashMap(); // maps potential output variables to associated lpn + // static private HashMap GlobalInterfaceMap = new HashMap(); // maps variables to initial values, input have null value until associated output is found + // static private HashMap> GlobalInputMap = new HashMap>(); // maps input variables to associated lpn + // static private HashMap> GlobalTranMap = new HashMap>(); // maps potential output variables to lpn transitions which affect it + // static private HashMap GlobalVarNodeMap = new HashMap(); // maps global variable name to variable object + + static private HashSet initMarkedPlaces = new HashSet(); + //static private HashSet initMarkedPlaces = new HashSet(); + + // non-static variables + private boolean Instance = false; + private HashMap VarNodeMap = null; // maps variable name to variable object + private HashMap ArrayNodeMap = null; // maps array variable name to variable object + private DualHashMap VarIndexMap = null; // maps variables to an array index + private HashMap GlobalConstHashMap = new HashMap(); // global constants within a single lpn file + private HashMap ConstHashMap = null; // constants within a single module + private HashMap StatevectorMap = null; // module variables mapped to initial values + private HashMap VarCountMap = null; // count of the references to each module variable + private List inputTranList = null; // list of lpn transitions which affect a modules input + private List outputTranList = null; // list of lpn transitions which affect a modules output + private VarSet Inputs = null; // module inputs + private VarSet Internals = null; // module internal variables + private VarSet Outputs = null; // module outputs + private int VariableIndex = 0; // count of index assigned to module variables + private int TransitionIndex = 0; + private int GlobalCount = 0; // number of global variables defined in this lpn file + private int GlobalSize = 0; // number of global variables defined + private String curLpn = ""; + // private boolean Instance = false; + // private HashMap VarNodeMap = null; // maps variable name to variable object + // private HashMap ArrayNodeMap = null; // maps array variable name to variable object + // private DualHashMap VarIndexMap = null; // maps variables to an array index + // private HashMap GlobalConstHashMap = new HashMap(); // global constants within a single lpn file + // private HashMap ConstHashMap = null; // constants within a single module + // private HashMap StatevectorMap = null; // module variables mapped to initial values + // private HashMap VarCountMap = null; // count of the references to each module variable + // private List inputTranList = null; // list of lpn transitions which affect a modules input + // private List outputTranList = null; // list of lpn transitions which affect a modules output + // private VarSet Inputs = null; // module inputs + // private VarSet Internals = null; // module internal variables + // private VarSet Outputs = null; // module outputs + + public enum VarType { + INPUT, OUTPUT, INTERNAL, GLOBAL + } + + + + // $ANTLR start "lpn" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:120:3: lpn returns [Set lpnSet] : ( ( globalConstants globalVariables ) | ( globalVariables globalConstants ) | ( globalVariables ) | ( globalConstants ) )? ( module | main )+ EOF ; + public final Set lpn() throws RecognitionException { + Set lpnSet = null; + + + LPN module1 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:121:5: ( ( ( globalConstants globalVariables ) | ( globalVariables globalConstants ) | ( globalVariables ) | ( globalConstants ) )? ( module | main )+ EOF ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:121:9: ( ( globalConstants globalVariables ) | ( globalVariables globalConstants ) | ( globalVariables ) | ( globalConstants ) )? ( module | main )+ EOF + { + lpnSet = new HashSet(); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:122:9: ( ( globalConstants globalVariables ) | ( globalVariables globalConstants ) | ( globalVariables ) | ( globalConstants ) )? + int alt1=5; + alt1 = dfa1.predict(input); + switch (alt1) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:122:10: ( globalConstants globalVariables ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:122:10: ( globalConstants globalVariables ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:122:11: globalConstants globalVariables + { + pushFollow(FOLLOW_globalConstants_in_lpn77); + globalConstants(); + + state._fsp--; + + + pushFollow(FOLLOW_globalVariables_in_lpn79); + globalVariables(); + + state._fsp--; + + + } + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:122:46: ( globalVariables globalConstants ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:122:46: ( globalVariables globalConstants ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:122:47: globalVariables globalConstants + { + pushFollow(FOLLOW_globalVariables_in_lpn85); + globalVariables(); + + state._fsp--; + + + pushFollow(FOLLOW_globalConstants_in_lpn87); + globalConstants(); + + state._fsp--; + + + } + + + } + break; + case 3 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:122:82: ( globalVariables ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:122:82: ( globalVariables ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:122:83: globalVariables + { + pushFollow(FOLLOW_globalVariables_in_lpn93); + globalVariables(); + + state._fsp--; + + + } + + + } + break; + case 4 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:122:102: ( globalConstants ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:122:102: ( globalConstants ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:122:103: globalConstants + { + pushFollow(FOLLOW_globalConstants_in_lpn99); + globalConstants(); + + state._fsp--; + + + } + + + } + break; + + } + + + + // check that global constants are consistently defined in each lpn file + if(GlobalSize > 0 && GlobalCount != GlobalSize){ + System.err.println("error: global variable definitions are inconsistent"); + System.exit(1); + } + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:130:8: ( module | main )+ + int cnt2=0; + loop2: + do { + int alt2=3; + int LA2_0 = input.LA(1); + + if ( (LA2_0==LESS) ) { + int LA2_2 = input.LA(2); + + if ( (LA2_2==MODULE) ) { + int LA2_3 = input.LA(3); + + if ( (LA2_3==NAME) ) { + int LA2_4 = input.LA(4); + + if ( (LA2_4==EQUALS) ) { + int LA2_5 = input.LA(5); + + if ( (LA2_5==QUOTE) ) { + int LA2_6 = input.LA(6); + + if ( (LA2_6==ID) ) { + alt2=1; + } + else if ( (LA2_6==63) ) { + alt2=2; + } + + + } + + + } + + + } + + + } + + + } + + + switch (alt2) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:130:9: module + { + pushFollow(FOLLOW_module_in_lpn124); + module1=module(); + + state._fsp--; + + + + lpnSet.add(module1); + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:134:11: main + { + pushFollow(FOLLOW_main_in_lpn151); + main(); + + state._fsp--; + + + + + + + } + break; + + default : + if ( cnt2 >= 1 ) break loop2; + EarlyExitException eee = + new EarlyExitException(2, input); + throw eee; + } + cnt2++; + } while (true); + + + match(input,EOF,FOLLOW_EOF_in_lpn176); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return lpnSet; + } + // $ANTLR end "lpn" + + + + // $ANTLR start "main" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:141:1: main : '<' 'mod' 'name' '=' '\"' 'main' '\"' '>' ( instantiation )+ '<' '/' 'mod' '>' ; + public final void main() throws RecognitionException { + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:142:2: ( '<' 'mod' 'name' '=' '\"' 'main' '\"' '>' ( instantiation )+ '<' '/' 'mod' '>' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:142:4: '<' 'mod' 'name' '=' '\"' 'main' '\"' '>' ( instantiation )+ '<' '/' 'mod' '>' + { + match(input,LESS,FOLLOW_LESS_in_main195); + + match(input,MODULE,FOLLOW_MODULE_in_main197); + + match(input,NAME,FOLLOW_NAME_in_main199); + + match(input,EQUALS,FOLLOW_EQUALS_in_main201); + + match(input,QUOTE,FOLLOW_QUOTE_in_main203); + + match(input,63,FOLLOW_63_in_main205); + + match(input,QUOTE,FOLLOW_QUOTE_in_main207); + + match(input,GREATER,FOLLOW_GREATER_in_main209); + + + if(main == true){ + System.err.println("error"); + System.exit(1); + } + + main = true; + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:151:3: ( instantiation )+ + int cnt3=0; + loop3: + do { + int alt3=2; + int LA3_0 = input.LA(1); + + if ( (LA3_0==LESS) ) { + int LA3_1 = input.LA(2); + + if ( (LA3_1==62) ) { + alt3=1; + } + + + } + + + switch (alt3) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:151:3: instantiation + { + pushFollow(FOLLOW_instantiation_in_main218); + instantiation(); + + state._fsp--; + + + } + break; + + default : + if ( cnt3 >= 1 ) break loop3; + EarlyExitException eee = + new EarlyExitException(3, input); + throw eee; + } + cnt3++; + } while (true); + + + match(input,LESS,FOLLOW_LESS_in_main221); + + match(input,DIV,FOLLOW_DIV_in_main223); + + match(input,MODULE,FOLLOW_MODULE_in_main225); + + match(input,GREATER,FOLLOW_GREATER_in_main227); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return ; + } + // $ANTLR end "main" + + + + // $ANTLR start "module" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:156:1: module returns [LhpnFile lpn] : ( '<' 'mod' 'name' '=' '\"' ID '\"' '>' ( constants )? variables ( instantiation )? ( logic )? '<' '/' 'mod' '>' ) ; + public final LPN module() throws RecognitionException { + LPN lpn = null; + + + Token ID2=null; + PlatuGrammarParser.logic_return logic3 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:157:5: ( ( '<' 'mod' 'name' '=' '\"' ID '\"' '>' ( constants )? variables ( instantiation )? ( logic )? '<' '/' 'mod' '>' ) ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:157:7: ( '<' 'mod' 'name' '=' '\"' ID '\"' '>' ( constants )? variables ( instantiation )? ( logic )? '<' '/' 'mod' '>' ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:157:7: ( '<' 'mod' 'name' '=' '\"' ID '\"' '>' ( constants )? variables ( instantiation )? ( logic )? '<' '/' 'mod' '>' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:157:9: '<' 'mod' 'name' '=' '\"' ID '\"' '>' ( constants )? variables ( instantiation )? ( logic )? '<' '/' 'mod' '>' + { + match(input,LESS,FOLLOW_LESS_in_module253); + + match(input,MODULE,FOLLOW_MODULE_in_module255); + + match(input,NAME,FOLLOW_NAME_in_module257); + + match(input,EQUALS,FOLLOW_EQUALS_in_module259); + + match(input,QUOTE,FOLLOW_QUOTE_in_module261); + + ID2=(Token)match(input,ID,FOLLOW_ID_in_module263); + + + // module names must be unique + if(LpnMap.containsKey((ID2!=null?ID2.getText():null))){ + System.err.println("error on line " + ID2.getLine() + ": module " + (ID2!=null?ID2.getText():null) + " already exists"); + System.exit(1); + } + + // initialize non static variables for new module + VarIndexMap = new DualHashMap(); + ConstHashMap = new HashMap(); + VarNodeMap = new HashMap(); + // TODO: Array Nodes + ArrayNodeMap = new HashMap(); + VarCountMap = new HashMap(); + Inputs = new VarSet(); + Internals = new VarSet(); + Outputs = new VarSet(); + inputTranList = new ArrayList();//inputTranList = new ArrayList(); + outputTranList = new ArrayList();//outputTranList = new ArrayList(); + StatevectorMap = new HashMap(); + VariableIndex = 0; + System.out.println("-------------------------"); + System.out.println("mod = " + (ID2!=null?ID2.getText():null)); + + + match(input,QUOTE,FOLLOW_QUOTE_in_module279); + + match(input,GREATER,FOLLOW_GREATER_in_module281); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:182:14: ( constants )? + int alt4=2; + int LA4_0 = input.LA(1); + + if ( (LA4_0==LESS) ) { + int LA4_1 = input.LA(2); + + if ( (LA4_1==60) ) { + alt4=1; + } + } + switch (alt4) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:182:14: constants + { + pushFollow(FOLLOW_constants_in_module283); + constants(); + + state._fsp--; + + + } + break; + + } + + + pushFollow(FOLLOW_variables_in_module286); + variables(); + + state._fsp--; + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:182:35: ( instantiation )? + int alt5=2; + int LA5_0 = input.LA(1); + + if ( (LA5_0==LESS) ) { + int LA5_1 = input.LA(2); + + if ( (LA5_1==62) ) { + alt5=1; + } + } + switch (alt5) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:182:35: instantiation + { + pushFollow(FOLLOW_instantiation_in_module288); + instantiation(); + + state._fsp--; + + + } + break; + + } + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:182:50: ( logic )? + int alt6=2; + int LA6_0 = input.LA(1); + + if ( (LA6_0==LESS) ) { + int LA6_1 = input.LA(2); + + if ( (LA6_1==MARKING||LA6_1==TRANSITION) ) { + alt6=1; + } + } + switch (alt6) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:182:50: logic + { + pushFollow(FOLLOW_logic_in_module291); + logic3=logic(); + + state._fsp--; + + + } + break; + + } + + + match(input,LESS,FOLLOW_LESS_in_module294); + + match(input,DIV,FOLLOW_DIV_in_module296); + + match(input,MODULE,FOLLOW_MODULE_in_module298); + + match(input,GREATER,FOLLOW_GREATER_in_module300); + + + for(Entry e : VarCountMap.entrySet()){ + if(e.getValue() == 0){ + System.out.println("warning: variable '" + e.getKey() + "' is never assigned"); + } + } + + // create new lpn + // Zone zone; + // if (Main.ZONE_VERSION == 2) { + // zone = new HashedHashedMapZoneImpl(); + // } + // else if (Main.ZONE_VERSION == 3) { + // zone = new HashedHashedMapZoneImpl(); + // } + // else { + // zone = new HashedHashedMapZoneImpl(); + // } + + // int i = 0; + // int[] initialMarking = new int[(logic3!=null?logic3.initMarking:null).size()]; + // for(Integer mark : (logic3!=null?logic3.initMarking:null)){ + // initialMarking[i++] = mark; + // } + + // lpn = new LPN(prj, (ID2!=null?ID2.getText():null), Inputs, Outputs, Internals, VarNodeMap, (logic3!=null?logic3.lpnTranSet:null), + // StatevectorMap, initialMarking); + lpn = new LPN(); + lpn.setLabel((ID2!=null?ID2.getText():null)); + System.out.println("---- LPN : " + lpn.getLabel() + " ----"); + for (Transition t: (logic3!=null?logic3.lpnTranSet:null)) { + lpn.addTransition(t); + t.setLpn(lpn); + System.out.println("transition(logic): " + t.getLabel()); + for (Place p : t.getPreset()) { + if ((logic3!=null?logic3.initMarking:null).contains(p.getName())) + lpn.addPlace(p.getName(), true); + else + lpn.addPlace(p.getName(), false); + lpn.getPlace(p.getName()).addPostset(t); + } + for (Place p : t.getPostset()) { + if ((logic3!=null?logic3.initMarking:null).contains(p.getName())) + lpn.addPlace(p.getName(), true); + else + lpn.addPlace(p.getName(), false); + lpn.getPlace(p.getName()).addPreset(t); + } + } + + // for(Transition tran : inputTranList){ + // tran.addDstLpn(lpn); + // } + // lpn.addAllInputTrans(inputTranList); + // lpn.addAllOutputTrans(outputTranList); + // lpn.setVarIndexMap(VarIndexMap); + // (logic3!=null?logic3.lpnTranSet:null).setLPN(lpn); + // prj.getDesignUnitSet().add(lpn.getStateGraph()); + + // for (Transition t : inputTranList) { + // System.out.println("transition(in): " + t.getLabel()); + // lpn.addTransition(t); + // } + for (Transition t : outputTranList) { + System.out.println("transition(out): " + t.getLabel()); + lpn.addTransition(t); + } + + LpnMap.put(lpn.getLabel(), lpn); + // for (String var : StatevectorMap.keySet()) { + // lpn.addInteger(var, StatevectorMap.get(var)+""); + // } + + // TODO: Where to use these hashmaps? + // map outputs to lpn object + for(String output : Outputs){ + GlobalOutputMap.put(output, lpn); + lpn.addOutput(output, "integer", StatevectorMap.get(output)+""); + System.out.println("@1: Added output variable " + output + " to LPN " + lpn.getLabel()); + } + // map potential output to lpn object + for(String internal : Internals){ + GlobalOutputMap.put(internal, lpn); + lpn.addInternal(internal, "integer", StatevectorMap.get(internal)+""); + System.out.println("@1: Added internal variable " + internal + " to LPN " + lpn.getLabel() + "with initial value " + StatevectorMap.get(internal)); + } + // map input variable to lpn object + for(String input : Inputs) { + if(GlobalInputMap.containsKey(input)){ + GlobalInputMap.get(input).add(lpn); + lpn.addInput(input, "integer", StatevectorMap.get(input)+""); + System.out.println("@1: Added input variable " + input + " to LPN " + lpn.getLabel() + " with initial value " + StatevectorMap.get(input) + "."); + } + else{ + List lpnList = new ArrayList();//List lpnList = new ArrayList(); + lpnList.add(lpn); + GlobalInputMap.put(input, lpnList); + lpn.addInput(input, "integer", StatevectorMap.get(input)+""); + System.out.println("@2: Added input variable " + input + " to LPN " + lpn.getLabel() + " with initial value " + StatevectorMap.get(input) + "."); + } + } + + + + } + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return lpn; + } + // $ANTLR end "module" + + + + // $ANTLR start "constants" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:289:1: constants : '<' 'const' '>' (const1= ID '=' val1= INT ';' )* '<' '/' 'const' '>' ; + public final void constants() throws RecognitionException { + Token const1=null; + Token val1=null; + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:290:2: ( '<' 'const' '>' (const1= ID '=' val1= INT ';' )* '<' '/' 'const' '>' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:290:4: '<' 'const' '>' (const1= ID '=' val1= INT ';' )* '<' '/' 'const' '>' + { + match(input,LESS,FOLLOW_LESS_in_constants327); + + match(input,60,FOLLOW_60_in_constants329); + + match(input,GREATER,FOLLOW_GREATER_in_constants331); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:290:20: (const1= ID '=' val1= INT ';' )* + loop7: + do { + int alt7=2; + int LA7_0 = input.LA(1); + + if ( (LA7_0==ID) ) { + alt7=1; + } + + + switch (alt7) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:290:21: const1= ID '=' val1= INT ';' + { + const1=(Token)match(input,ID,FOLLOW_ID_in_constants336); + + match(input,EQUALS,FOLLOW_EQUALS_in_constants338); + + val1=(Token)match(input,INT,FOLLOW_INT_in_constants342); + + + // make sure constant is not defined as something else + // String const1_tmp = (const1!=null?const1.getText():null); + // if ((const1!=null?const1.getText():null).contains(".")) { + // const1_tmp.replaceAll(".", "_"); + // } + // else { + // const1_tmp = (const1!=null?const1.getText():null); + // } + + String const1_tmp = (const1!=null?const1.getText():null); + if ((const1!=null?const1.getText():null).contains(".")) { + const1_tmp = const1_tmp.replace(".", "_"); + } + else { + const1_tmp = (const1!=null?const1.getText():null); + } + if(StatevectorMap.containsKey(const1_tmp)){ + System.err.println("error on line " + const1.getLine() + ": " + (const1!=null?const1.getText():null) + " already exists as a variable"); + System.exit(1); + } + else if(GlobalConstHashMap.containsKey(const1_tmp)){ + System.err.println("error on line " + const1.getLine() + ": " + (const1!=null?const1.getText():null) + " already exists as a global constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey(const1_tmp)){ + System.err.println("error on line " + const1.getLine() + ": " + (const1!=null?const1.getText():null) + " is already defined as a global variable"); + System.exit(1); + } + // put will override previous value + //Integer result = ConstHashMap.put((const1!=null?const1.getText():null), Integer.parseInt((val1!=null?val1.getText():null))); + Integer result = ConstHashMap.put(const1_tmp, Integer.parseInt((val1!=null?val1.getText():null))); + if(result != null){ + System.err.println("warning on line " + const1.getLine() + ": " + (const1!=null?const1.getText():null) + " will be overwritten"); + } + + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_constants353); + + } + break; + + default : + break loop7; + } + } while (true); + + + match(input,LESS,FOLLOW_LESS_in_constants357); + + match(input,DIV,FOLLOW_DIV_in_constants359); + + match(input,60,FOLLOW_60_in_constants361); + + match(input,GREATER,FOLLOW_GREATER_in_constants363); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return ; + } + // $ANTLR end "constants" + + + + // $ANTLR start "globalConstants" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:330:1: globalConstants : '<' 'const' '>' (const1= ID '=' val1= INT ';' )* '<' '/' 'const' '>' ; + public final void globalConstants() throws RecognitionException { + Token const1=null; + Token val1=null; + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:331:5: ( '<' 'const' '>' (const1= ID '=' val1= INT ';' )* '<' '/' 'const' '>' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:331:9: '<' 'const' '>' (const1= ID '=' val1= INT ';' )* '<' '/' 'const' '>' + { + match(input,LESS,FOLLOW_LESS_in_globalConstants379); + + match(input,60,FOLLOW_60_in_globalConstants381); + + match(input,GREATER,FOLLOW_GREATER_in_globalConstants383); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:331:25: (const1= ID '=' val1= INT ';' )* + loop8: + do { + int alt8=2; + int LA8_0 = input.LA(1); + + if ( (LA8_0==ID) ) { + alt8=1; + } + + + switch (alt8) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:331:26: const1= ID '=' val1= INT ';' + { + const1=(Token)match(input,ID,FOLLOW_ID_in_globalConstants388); + + match(input,EQUALS,FOLLOW_EQUALS_in_globalConstants390); + + val1=(Token)match(input,INT,FOLLOW_INT_in_globalConstants394); + + + String const1_tmp = (const1!=null?const1.getText():null); + if ((const1!=null?const1.getText():null).contains(".")) { + const1_tmp = const1_tmp.replace(".", "_"); + } + else { + const1_tmp = (const1!=null?const1.getText():null); + } + // make sure constant has not been defined already + if(GlobalVarHashMap.containsKey(const1_tmp)){ + System.err.println("error on line " + const1.getLine() + ": " + (const1!=null?const1.getText():null) + " is already defined as a global variable"); + System.exit(1); + } + + // put will override previous value + Integer result = GlobalConstHashMap.put(const1_tmp, Integer.parseInt((val1!=null?val1.getText():null))); + if(result != null){ + System.err.println("warning on line " + const1.getLine() + ": " + (const1!=null?const1.getText():null) + " will be overwritten"); + } + + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_globalConstants420); + + } + break; + + default : + break loop8; + } + } while (true); + + + match(input,LESS,FOLLOW_LESS_in_globalConstants424); + + match(input,DIV,FOLLOW_DIV_in_globalConstants426); + + match(input,60,FOLLOW_60_in_globalConstants428); + + match(input,GREATER,FOLLOW_GREATER_in_globalConstants430); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return ; + } + // $ANTLR end "globalConstants" + + + + // $ANTLR start "globalVariables" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:355:1: globalVariables : '<' 'var' '>' (var= ID '=' (val= INT |var2= ID ) ';' )* '<' '/' 'var' '>' ; + public final void globalVariables() throws RecognitionException { + Token var=null; + Token val=null; + Token var2=null; + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:356:2: ( '<' 'var' '>' (var= ID '=' (val= INT |var2= ID ) ';' )* '<' '/' 'var' '>' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:356:4: '<' 'var' '>' (var= ID '=' (val= INT |var2= ID ) ';' )* '<' '/' 'var' '>' + { + match(input,LESS,FOLLOW_LESS_in_globalVariables444); + + match(input,INTERNAL,FOLLOW_INTERNAL_in_globalVariables446); + + match(input,GREATER,FOLLOW_GREATER_in_globalVariables448); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:356:18: (var= ID '=' (val= INT |var2= ID ) ';' )* + loop10: + do { + int alt10=2; + int LA10_0 = input.LA(1); + + if ( (LA10_0==ID) ) { + alt10=1; + } + + + switch (alt10) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:356:19: var= ID '=' (val= INT |var2= ID ) ';' + { + var=(Token)match(input,ID,FOLLOW_ID_in_globalVariables453); + + + // make sure global variables are consistently defined in each lpn file + String var_tmp = (var!=null?var.getText():null); + if ((var!=null?var.getText():null).contains(".")) { + var_tmp = var_tmp.replace(".", "_"); + } + else { + var_tmp = (var!=null?var.getText():null); + } + if(GlobalSize == 0){ + if(GlobalConstHashMap.containsKey(var_tmp)){ + System.err.println("error on line" + var.getLine() + ": " + (var!=null?var.getText():null) + "already exists as a constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey(var_tmp)){ + System.err.println("error on line " + var.getLine() + ": " + (var!=null?var.getText():null) + " has already been defined"); + System.exit(1); + } + } + else{ + if(!GlobalVarHashMap.containsKey(var_tmp)){ + System.err.println("error on line " + var.getLine() + ": " + (var!=null?var.getText():null) + " is inconsistently defined"); + System.exit(1); + } + } + + GlobalCount++; + + + match(input,EQUALS,FOLLOW_EQUALS_in_globalVariables463); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:385:7: (val= INT |var2= ID ) + int alt9=2; + int LA9_0 = input.LA(1); + + if ( (LA9_0==INT) ) { + alt9=1; + } + else if ( (LA9_0==ID) ) { + alt9=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 9, 0, input); + + throw nvae; + + } + switch (alt9) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:385:8: val= INT + { + val=(Token)match(input,INT,FOLLOW_INT_in_globalVariables468); + + + // make sure global variables are consistently initialized + int value = Integer.parseInt((val!=null?val.getText():null)); + if(GlobalSize == 0){ + GlobalVarHashMap.put(var_tmp, value); + } + else{ + int globalVal = GlobalVarHashMap.get(var_tmp); + if(globalVal != value){ + System.err.println("error on line " + val.getLine() + ": " + (var!=null?var.getText():null) + " is inconsistently assigned"); + System.exit(1); + } + } + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:400:5: var2= ID + { + var2=(Token)match(input,ID,FOLLOW_ID_in_globalVariables482); + + + String var2_tmp = (var2!=null?var2.getText():null); + if ((var2!=null?var2.getText():null).contains(".")) { + var2_tmp = var2_tmp.replace(".", "_"); + } + else { + var2_tmp = (var2!=null?var2.getText():null); + } + // get value of variable + Integer value = null; + if(GlobalConstHashMap.containsKey(var2_tmp)){ + value = GlobalConstHashMap.get(var2_tmp); + } + else if(GlobalVarHashMap.containsKey(var2_tmp)){ + System.err.println("error on line " + var2.getLine() + ": global variable " + (var2!=null?var2.getText():null) + " cannot be assigned to global variable " + (var!=null?var.getText():null)); + System.exit(1); + } + else{ + System.err.println("error on line " + var2.getLine() + ": " + (var2!=null?var2.getText():null) + " is not defined"); + System.exit(1); + } + // make sure global variable is consistently initialized + if(GlobalSize == 0){ + GlobalVarHashMap.put(var2_tmp, value); + } + else{ + int globalVal = GlobalVarHashMap.get(var2_tmp); + if(globalVal != value){ + System.err.println("error on line " + val.getLine() + ": " + (var!=null?var.getText():null) + " is inconsistently assigned"); + System.exit(1); + } + } + + + } + break; + + } + + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_globalVariables492); + + } + break; + + default : + break loop10; + } + } while (true); + + + match(input,LESS,FOLLOW_LESS_in_globalVariables496); + + match(input,DIV,FOLLOW_DIV_in_globalVariables498); + + match(input,INTERNAL,FOLLOW_INTERNAL_in_globalVariables500); + + match(input,GREATER,FOLLOW_GREATER_in_globalVariables502); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return ; + } + // $ANTLR end "globalVariables" + + + + // $ANTLR start "variables" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:438:1: variables : '<' 'var' '>' ( (var= ID '=' (val= INT |var2= ID ) ';' ) | (arrayName= ID ( '[' (dim= ID |val2= INT ) ']' )+ '=' ( '(' (val3= INT ',' )* val4= INT ')' )+ ';' ) )* '<' '/' 'var' '>' ; + public final void variables() throws RecognitionException { + Token var=null; + Token val=null; + Token var2=null; + Token arrayName=null; + Token dim=null; + Token val2=null; + Token val3=null; + Token val4=null; + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:439:2: ( '<' 'var' '>' ( (var= ID '=' (val= INT |var2= ID ) ';' ) | (arrayName= ID ( '[' (dim= ID |val2= INT ) ']' )+ '=' ( '(' (val3= INT ',' )* val4= INT ')' )+ ';' ) )* '<' '/' 'var' '>' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:439:4: '<' 'var' '>' ( (var= ID '=' (val= INT |var2= ID ) ';' ) | (arrayName= ID ( '[' (dim= ID |val2= INT ) ']' )+ '=' ( '(' (val3= INT ',' )* val4= INT ')' )+ ';' ) )* '<' '/' 'var' '>' + { + Integer value = null; Token varNode = null; String var_tmp; + + match(input,LESS,FOLLOW_LESS_in_variables518); + + match(input,INTERNAL,FOLLOW_INTERNAL_in_variables520); + + match(input,GREATER,FOLLOW_GREATER_in_variables522); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:440:17: ( (var= ID '=' (val= INT |var2= ID ) ';' ) | (arrayName= ID ( '[' (dim= ID |val2= INT ) ']' )+ '=' ( '(' (val3= INT ',' )* val4= INT ')' )+ ';' ) )* + loop16: + do { + int alt16=3; + int LA16_0 = input.LA(1); + + if ( (LA16_0==ID) ) { + int LA16_2 = input.LA(2); + + if ( (LA16_2==EQUALS) ) { + alt16=1; + } + else if ( (LA16_2==57) ) { + alt16=2; + } + + + } + + + switch (alt16) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:440:18: (var= ID '=' (val= INT |var2= ID ) ';' ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:440:18: (var= ID '=' (val= INT |var2= ID ) ';' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:440:19: var= ID '=' (val= INT |var2= ID ) ';' + { + var=(Token)match(input,ID,FOLLOW_ID_in_variables528); + + + // check variable is unique in scope + var_tmp = (var!=null?var.getText():null); + if ((var!=null?var.getText():null).contains(".")) { + var_tmp = var_tmp.replace(".", "_"); + } + else { + var_tmp = (var!=null?var.getText():null); + } + if(GlobalConstHashMap.containsKey(var_tmp)){ + System.err.println("error on line " + var.getLine() + ": " + (var!=null?var.getText():null) + " is a global constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey(var_tmp)){ + System.err.println("error on line " + var.getLine() + ": " + (var!=null?var.getText():null) + " is a global variable"); + System.exit(1); + } + else if(StatevectorMap.containsKey(var_tmp)){ + System.err.println("warning on line " + var.getLine() + ": " + (var!=null?var.getText():null) + " will be overwritten"); + } + varNode = var; + + + match(input,EQUALS,FOLLOW_EQUALS_in_variables538); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:463:7: (val= INT |var2= ID ) + int alt11=2; + int LA11_0 = input.LA(1); + + if ( (LA11_0==INT) ) { + alt11=1; + } + else if ( (LA11_0==ID) ) { + alt11=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 11, 0, input); + + throw nvae; + + } + switch (alt11) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:463:8: val= INT + { + val=(Token)match(input,INT,FOLLOW_INT_in_variables543); + + + // get variable initial value + value = Integer.parseInt((val!=null?val.getText():null)); + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:468:5: var2= ID + { + var2=(Token)match(input,ID,FOLLOW_ID_in_variables557); + + + String var2_tmp = (var2!=null?var2.getText():null); + if ((var2!=null?var2.getText():null).contains(".")) { + var2_tmp = var2_tmp.replace(".", "_"); + } + else { + var2_tmp = (var2!=null?var2.getText():null); + } + // get variable initial value + if(GlobalConstHashMap.containsKey(var2_tmp)){ + value = GlobalConstHashMap.get(var2_tmp); + } + else if(GlobalVarHashMap.containsKey(var2_tmp)){ + value = GlobalVarHashMap.get(var2_tmp); + } + else if(ConstHashMap.containsKey(var2_tmp)){ + value = ConstHashMap.get(var2_tmp); + } + else if(StatevectorMap.containsKey(var2_tmp)){ // Should var be allowed to assign a var? + value = StatevectorMap.get(var2_tmp); + } + else{ + System.err.println("error on line " + var2.getLine() + ": " + (var2!=null?var2.getText():null) + " is not defined"); + System.exit(1); + } + + varNode = var2; + var_tmp = var2_tmp; + + + } + break; + + } + + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_variables567); + + } + + + + // add variable and value to state vector + //StatevectorMap.put(varNode.getText(), value); + StatevectorMap.put(var_tmp, value); + + // generate variable index and create new var node + int index = VariableIndex++; + //VarIndexMap.insert(varNode.getText(), index); + VarIndexMap.insert(var_tmp, index); + ExprTree newVarNode = new ExprTree(var_tmp); + newVarNode.setIntegerSignals(StatevectorMap.keySet()); + newVarNode.getExprTree(); + VarNodeMap.put(var_tmp, newVarNode); + + //VarNodeMap.put(varNode.getText(), new ExprTree(varNode.getText())); + //VarNodeMap.put(varNode.getText(), new VarNode(varNode.getText(), index)); + + // if associated input variable has been defined, label as output, else label as internal + if(!GlobalInterfaceMap.containsKey(var_tmp)){ + Internals.add(var_tmp); + } + else{ + if(GlobalInterfaceMap.get(varNode.getText()) != null){ + System.err.println("error on line " + varNode.getLine() + ": variable '" + varNode.getText() + "' has already been declared in another module"); + System.exit(1); + } + Outputs.add(var_tmp); + // TODO: Is it needed for our LPN? + // initialize associated input variables with output value + List lpnList = GlobalInputMap.get(var_tmp); + if(lpnList != null){ + for(LPN lpn : lpnList){ + //lpn.getInitVector().put(varNode.getText(), value); + //(delete) lpn.addInput(var_tmp, "integer", value+""); + } + } + } + GlobalInterfaceMap.put(var_tmp, value); + VarCountMap.put(var_tmp, 0); + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:540:5: (arrayName= ID ( '[' (dim= ID |val2= INT ) ']' )+ '=' ( '(' (val3= INT ',' )* val4= INT ')' )+ ';' ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:540:5: (arrayName= ID ( '[' (dim= ID |val2= INT ) ']' )+ '=' ( '(' (val3= INT ',' )* val4= INT ')' )+ ';' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:540:6: arrayName= ID ( '[' (dim= ID |val2= INT ) ']' )+ '=' ( '(' (val3= INT ',' )* val4= INT ')' )+ ';' + { + arrayName=(Token)match(input,ID,FOLLOW_ID_in_variables586); + + + List dimensionsList = new ArrayList(); + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:544:3: ( '[' (dim= ID |val2= INT ) ']' )+ + int cnt13=0; + loop13: + do { + int alt13=2; + int LA13_0 = input.LA(1); + + if ( (LA13_0==57) ) { + alt13=1; + } + + + switch (alt13) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:544:4: '[' (dim= ID |val2= INT ) ']' + { + match(input,57,FOLLOW_57_in_variables596); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:544:8: (dim= ID |val2= INT ) + int alt12=2; + int LA12_0 = input.LA(1); + + if ( (LA12_0==ID) ) { + alt12=1; + } + else if ( (LA12_0==INT) ) { + alt12=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 12, 0, input); + + throw nvae; + + } + switch (alt12) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:544:9: dim= ID + { + dim=(Token)match(input,ID,FOLLOW_ID_in_variables601); + + + // get variable value + if(GlobalConstHashMap.containsKey((dim!=null?dim.getText():null))){ + value = GlobalConstHashMap.get((dim!=null?dim.getText():null)); + } + else if(GlobalVarHashMap.containsKey((dim!=null?dim.getText():null))){ + value = GlobalVarHashMap.get((dim!=null?dim.getText():null)); + } + else if(ConstHashMap.containsKey((dim!=null?dim.getText():null))){ + value = ConstHashMap.get((dim!=null?dim.getText():null)); + } + else if(StatevectorMap.containsKey((dim!=null?dim.getText():null))){ // Should var be allowed to assign a var? + value = StatevectorMap.get((dim!=null?dim.getText():null)); + } + else{ + System.err.println("error on line " + dim.getLine() + ": " + (dim!=null?dim.getText():null) + " is not defined"); + System.exit(1); + } + + dimensionsList.add(value); + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:566:5: val2= INT + { + val2=(Token)match(input,INT,FOLLOW_INT_in_variables615); + + + dimensionsList.add(Integer.parseInt((val2!=null?val2.getText():null))); + + + } + break; + + } + + + match(input,58,FOLLOW_58_in_variables626); + + } + break; + + default : + if ( cnt13 >= 1 ) break loop13; + EarlyExitException eee = + new EarlyExitException(13, input); + throw eee; + } + cnt13++; + } while (true); + + + match(input,EQUALS,FOLLOW_EQUALS_in_variables631); + + + List valueList = new ArrayList(); + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:574:3: ( '(' (val3= INT ',' )* val4= INT ')' )+ + int cnt15=0; + loop15: + do { + int alt15=2; + int LA15_0 = input.LA(1); + + if ( (LA15_0==LPAREN) ) { + alt15=1; + } + + + switch (alt15) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:574:4: '(' (val3= INT ',' )* val4= INT ')' + { + match(input,LPAREN,FOLLOW_LPAREN_in_variables642); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:574:8: (val3= INT ',' )* + loop14: + do { + int alt14=2; + int LA14_0 = input.LA(1); + + if ( (LA14_0==INT) ) { + int LA14_1 = input.LA(2); + + if ( (LA14_1==COMMA) ) { + alt14=1; + } + + + } + + + switch (alt14) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:574:9: val3= INT ',' + { + val3=(Token)match(input,INT,FOLLOW_INT_in_variables647); + + match(input,COMMA,FOLLOW_COMMA_in_variables649); + + + valueList.add(Integer.parseInt((val3!=null?val3.getText():null))); + + + } + break; + + default : + break loop14; + } + } while (true); + + + val4=(Token)match(input,INT,FOLLOW_INT_in_variables663); + + + valueList.add(Integer.parseInt((val4!=null?val4.getText():null))); + + + match(input,RPAREN,FOLLOW_RPAREN_in_variables673); + + } + break; + + default : + if ( cnt15 >= 1 ) break loop15; + EarlyExitException eee = + new EarlyExitException(15, input); + throw eee; + } + cnt15++; + } while (true); + + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_variables680); + + + if(valueList.size() != dimensionsList.get(0)){ + System.err.println("error: incompatible number of elements in " + (arrayName!=null?arrayName.getText():null)); + System.exit(1); + } + + if(dimensionsList.size() == 1){ + int varCount = 0; + int arraySize = dimensionsList.get(0); + List array = new ArrayList(arraySize); + for(int i = 0; i < arraySize; i++){ + String name = (arrayName!=null?arrayName.getText():null) + varCount++; + int index = VariableIndex++; + //VarNode v = new VarNode(name, index); + ExprTree v = new ExprTree(name); + array.add(v); + + // add variable and value to state vector + StatevectorMap.put(name, 0); + + // generate variable index and create new var node + VarIndexMap.insert(name, index); + } + // TODO: ArrayNodeMap? + // ArrayNodeMap.put((arrayName!=null?arrayName.getText():null), new ArrayNode((arrayName!=null?arrayName.getText():null), array, 1)); + VarCountMap.put((arrayName!=null?arrayName.getText():null), 0); + } + else{ + } + + + } + + + } + break; + + default : + break loop16; + } + } while (true); + + + match(input,LESS,FOLLOW_LESS_in_variables694); + + match(input,DIV,FOLLOW_DIV_in_variables696); + + match(input,INTERNAL,FOLLOW_INTERNAL_in_variables698); + + match(input,GREATER,FOLLOW_GREATER_in_variables700); + + + // add global variables to initial state vector and label as an input & output + System.out.println("GlobalVarHashMap size = " + GlobalVarHashMap.size()); + for(Entry e : GlobalVarHashMap.entrySet()){ + String globalVar = e.getKey(); + StatevectorMap.put(globalVar, e.getValue()); + Integer index = VariableIndex++; + VarIndexMap.insert(globalVar, index); + //VarNodeMap.put(globalVar, new VarNode(globalVar, index)); + VarNodeMap.put(globalVar, new ExprTree(globalVar)); + Inputs.add(globalVar); + System.out.println("Added globalVar (" + globalVar + ") to Inputs."); + Outputs.add(globalVar); + } + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return ; + } + // $ANTLR end "variables" + + + + // $ANTLR start "instantiation" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:632:1: instantiation : '<' 'inst' '>' modName= ID instName= ID '(' (mod= ID '.' var= ID )+ ')' '<' '/' 'inst' '>' ; + public final void instantiation() throws RecognitionException { + Token modName=null; + Token instName=null; + Token mod=null; + Token var=null; + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:633:5: ( '<' 'inst' '>' modName= ID instName= ID '(' (mod= ID '.' var= ID )+ ')' '<' '/' 'inst' '>' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:633:9: '<' 'inst' '>' modName= ID instName= ID '(' (mod= ID '.' var= ID )+ ')' '<' '/' 'inst' '>' + { + HashMap portMap = new HashMap(); + + match(input,LESS,FOLLOW_LESS_in_instantiation729); + + match(input,62,FOLLOW_62_in_instantiation731); + + match(input,GREATER,FOLLOW_GREATER_in_instantiation733); + + modName=(Token)match(input,ID,FOLLOW_ID_in_instantiation742); + + instName=(Token)match(input,ID,FOLLOW_ID_in_instantiation746); + + match(input,LPAREN,FOLLOW_LPAREN_in_instantiation748); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:635:32: (mod= ID '.' var= ID )+ + int cnt17=0; + loop17: + do { + int alt17=2; + int LA17_0 = input.LA(1); + + if ( (LA17_0==ID) ) { + alt17=1; + } + + + switch (alt17) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:635:33: mod= ID '.' var= ID + { + mod=(Token)match(input,ID,FOLLOW_ID_in_instantiation752); + + match(input,PERIOD,FOLLOW_PERIOD_in_instantiation754); + + var=(Token)match(input,ID,FOLLOW_ID_in_instantiation758); + + } + break; + + default : + if ( cnt17 >= 1 ) break loop17; + EarlyExitException eee = + new EarlyExitException(17, input); + throw eee; + } + cnt17++; + } while (true); + + + match(input,RPAREN,FOLLOW_RPAREN_in_instantiation762); + + match(input,LESS,FOLLOW_LESS_in_instantiation769); + + match(input,DIV,FOLLOW_DIV_in_instantiation771); + + match(input,62,FOLLOW_62_in_instantiation773); + + match(input,GREATER,FOLLOW_GREATER_in_instantiation775); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return ; + } + // $ANTLR end "instantiation" + + + public static class logic_return extends ParserRuleReturnScope { + public List initMarking; + public LpnTranList lpnTranSet; + }; + + + // $ANTLR start "logic" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:639:1: logic returns [List initMarking, LpnTranList lpnTranSet] : marking ( transition )+ ; + public final PlatuGrammarParser.logic_return logic() throws RecognitionException { + PlatuGrammarParser.logic_return retval = new PlatuGrammarParser.logic_return(); + retval.start = input.LT(1); + + + Transition transition4 =null; + + List marking5 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:640:5: ( marking ( transition )+ ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:640:9: marking ( transition )+ + { + retval.lpnTranSet = new LpnTranList(); + + pushFollow(FOLLOW_marking_in_logic805); + marking5=marking(); + + state._fsp--; + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:641:14: ( transition )+ + int cnt18=0; + loop18: + do { + int alt18=2; + int LA18_0 = input.LA(1); + + if ( (LA18_0==LESS) ) { + int LA18_1 = input.LA(2); + + if ( (LA18_1==TRANSITION) ) { + alt18=1; + } + + + } + + + switch (alt18) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:641:15: transition + { + pushFollow(FOLLOW_transition_in_logic808); + transition4=transition(); + + state._fsp--; + + + retval.lpnTranSet.add(transition4); + + } + break; + + default : + if ( cnt18 >= 1 ) break loop18; + EarlyExitException eee = + new EarlyExitException(18, input); + throw eee; + } + cnt18++; + } while (true); + + + + retval.initMarking = marking5; + + + } + + retval.stop = input.LT(-1); + + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "logic" + + + + // $ANTLR start "marking" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:647:1: marking returns [List mark] : ( '<' 'marking' '>' ( (m1= INT |c1= ID ) ( ',' (m2= INT |c2= ID ) )* )? '<' '/' 'marking' '>' )? ; + public final List marking() throws RecognitionException { + List mark = null; + + + Token m1=null; + Token c1=null; + Token m2=null; + Token c2=null; + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:648:5: ( ( '<' 'marking' '>' ( (m1= INT |c1= ID ) ( ',' (m2= INT |c2= ID ) )* )? '<' '/' 'marking' '>' )? ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:648:9: ( '<' 'marking' '>' ( (m1= INT |c1= ID ) ( ',' (m2= INT |c2= ID ) )* )? '<' '/' 'marking' '>' )? + { + mark = new LinkedList(); Integer result; + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:649:9: ( '<' 'marking' '>' ( (m1= INT |c1= ID ) ( ',' (m2= INT |c2= ID ) )* )? '<' '/' 'marking' '>' )? + int alt23=2; + int LA23_0 = input.LA(1); + + if ( (LA23_0==LESS) ) { + int LA23_1 = input.LA(2); + + if ( (LA23_1==MARKING) ) { + alt23=1; + } + } + switch (alt23) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:649:10: '<' 'marking' '>' ( (m1= INT |c1= ID ) ( ',' (m2= INT |c2= ID ) )* )? '<' '/' 'marking' '>' + { + match(input,LESS,FOLLOW_LESS_in_marking862); + + match(input,MARKING,FOLLOW_MARKING_in_marking864); + + match(input,GREATER,FOLLOW_GREATER_in_marking866); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:649:28: ( (m1= INT |c1= ID ) ( ',' (m2= INT |c2= ID ) )* )? + int alt22=2; + int LA22_0 = input.LA(1); + + if ( (LA22_0==ID||LA22_0==INT) ) { + alt22=1; + } + switch (alt22) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:649:29: (m1= INT |c1= ID ) ( ',' (m2= INT |c2= ID ) )* + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:649:29: (m1= INT |c1= ID ) + int alt19=2; + int LA19_0 = input.LA(1); + + if ( (LA19_0==INT) ) { + alt19=1; + } + else if ( (LA19_0==ID) ) { + alt19=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 19, 0, input); + + throw nvae; + + } + switch (alt19) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:649:30: m1= INT + { + m1=(Token)match(input,INT,FOLLOW_INT_in_marking872); + + + // mark.add(Integer.parseInt((m1!=null?m1.getText():null))); + // initMarkedPlaces.add(Integer.parseInt((m1!=null?m1.getText():null))); + mark.add("p" + (m1!=null?m1.getText():null)); + initMarkedPlaces.add("p" + (m1!=null?m1.getText():null)); + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:656:11: c1= ID + { + c1=(Token)match(input,ID,FOLLOW_ID_in_marking898); + + + String c1_tmp = (c1!=null?c1.getText():null); + if ((c1!=null?c1.getText():null).contains(".")) { + c1_tmp = c1_tmp.replace(".", "_"); + } + else { + c1_tmp = (c1!=null?c1.getText():null); + } + // result = ConstHashMap.get(c1_tmp); + // if(result == null){ + // System.err.println("error on line " + c1.getLine() + ": " + (c1!=null?c1.getText():null) + " is not a valid constant"); + // System.exit(1); + // } + // mark.add(result); + // initMarkedPlaces.add(Integer.parseInt((m1!=null?m1.getText():null))); + mark.add(c1_tmp); + initMarkedPlaces.add(c1_tmp); + + + } + break; + + } + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:675:11: ( ',' (m2= INT |c2= ID ) )* + loop21: + do { + int alt21=2; + int LA21_0 = input.LA(1); + + if ( (LA21_0==COMMA) ) { + alt21=1; + } + + + switch (alt21) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:675:12: ',' (m2= INT |c2= ID ) + { + match(input,COMMA,FOLLOW_COMMA_in_marking922); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:675:16: (m2= INT |c2= ID ) + int alt20=2; + int LA20_0 = input.LA(1); + + if ( (LA20_0==INT) ) { + alt20=1; + } + else if ( (LA20_0==ID) ) { + alt20=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 20, 0, input); + + throw nvae; + + } + switch (alt20) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:675:17: m2= INT + { + m2=(Token)match(input,INT,FOLLOW_INT_in_marking927); + + + // mark.add(Integer.parseInt((m2!=null?m2.getText():null))); + // initMarkedPlaces.add(Integer.parseInt((m2!=null?m2.getText():null))); + mark.add("p"+(m2!=null?m2.getText():null)); + initMarkedPlaces.add("p" +(m2!=null?m2.getText():null)); + + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:683:11: c2= ID + { + c2=(Token)match(input,ID,FOLLOW_ID_in_marking953); + + + String c2_tmp = (c2!=null?c2.getText():null); + if ((c2!=null?c2.getText():null).contains(".")) { + c2_tmp = c2_tmp.replace(".", "_"); + } + else { + c2_tmp = (c2!=null?c2.getText():null); + } + // result = ConstHashMap.get(c2_tmp); + // if(result == null){ + // System.err.println("error on line " + c2.getLine() + ": " + (c2!=null?c2.getText():null) + " is not a valid constant"); + // System.exit(1); + // } + // mark.add(result); + // initMarkedPlaces.add(result); + mark.add(c2_tmp); + initMarkedPlaces.add(c2_tmp); + + + } + break; + + } + + + } + break; + + default : + break loop21; + } + } while (true); + + + } + break; + + } + + + match(input,LESS,FOLLOW_LESS_in_marking980); + + match(input,DIV,FOLLOW_DIV_in_marking982); + + match(input,MARKING,FOLLOW_MARKING_in_marking984); + + match(input,GREATER,FOLLOW_GREATER_in_marking986); + + } + break; + + } + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return mark; + } + // $ANTLR end "marking" + + + + // $ANTLR start "transition" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:705:1: transition returns [Transition lpnTran] : '<' 'transition' 'label' '=' '\"' lbl= ( ID | INT ) '\"' 'preset' '=' ( '\"' '\"' | ( '\"' (pre= INT |pre1= ID ) ( ',' pre2= INT | ',' pre3= ID )* '\"' ) ) 'postset' '=' ( '\"' '\"' | ( '\"' (post= INT |post1= ID ) ( ( ',' post2= INT ) | ( ',' post3= ID ) )* '\"' ) ) '>' ( guard )? ( delay )? ( ( assertion ) | ( assignment ) )* '<' '/' 'transition' '>' ; + public final Transition transition() throws RecognitionException { + Transition lpnTran = null; + + + Token lbl=null; + Token pre=null; + Token pre1=null; + Token pre2=null; + Token pre3=null; + Token post=null; + Token post1=null; + Token post2=null; + Token post3=null; + ExprTree guard6 =null; + + PlatuGrammarParser.delay_return delay7 =null; + + ExprTree assertion8 =null; + + HashMap assignment9 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:706:5: ( '<' 'transition' 'label' '=' '\"' lbl= ( ID | INT ) '\"' 'preset' '=' ( '\"' '\"' | ( '\"' (pre= INT |pre1= ID ) ( ',' pre2= INT | ',' pre3= ID )* '\"' ) ) 'postset' '=' ( '\"' '\"' | ( '\"' (post= INT |post1= ID ) ( ( ',' post2= INT ) | ( ',' post3= ID ) )* '\"' ) ) '>' ( guard )? ( delay )? ( ( assertion ) | ( assignment ) )* '<' '/' 'transition' '>' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:706:10: '<' 'transition' 'label' '=' '\"' lbl= ( ID | INT ) '\"' 'preset' '=' ( '\"' '\"' | ( '\"' (pre= INT |pre1= ID ) ( ',' pre2= INT | ',' pre3= ID )* '\"' ) ) 'postset' '=' ( '\"' '\"' | ( '\"' (post= INT |post1= ID ) ( ( ',' post2= INT ) | ( ',' post3= ID ) )* '\"' ) ) '>' ( guard )? ( delay )? ( ( assertion ) | ( assignment ) )* '<' '/' 'transition' '>' + { + + Integer result = null; + //ArrayList presetList = new ArrayList(); + // VarExprList assignmentList = new VarExprList(); + // ArrayList assertionList = new ArrayList(); + // Expression guardExpr = TrueExpr; + // int delayLB = 0; + // int delayUB = INFINITY; + // boolean local = true; + + ArrayList presetList = new ArrayList(); + ArrayList postsetList = new ArrayList(); + HashMap assignmentList = new HashMap(); + // TODO: Need to deal with assertionList + //ArrayList assertionList = new ArrayList(); + ArrayList assertionList = new ArrayList(); + ExprTree guardExpr = null; + int delayLB = 0; + int delayUB = INFINITY; + boolean local = true; + + + + match(input,LESS,FOLLOW_LESS_in_transition1020); + + match(input,TRANSITION,FOLLOW_TRANSITION_in_transition1022); + + match(input,LABEL,FOLLOW_LABEL_in_transition1024); + + match(input,EQUALS,FOLLOW_EQUALS_in_transition1026); + + match(input,QUOTE,FOLLOW_QUOTE_in_transition1028); + + lbl=(Token)input.LT(1); + + if ( input.LA(1)==ID||input.LA(1)==INT ) { + input.consume(); + state.errorRecovery=false; + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + throw mse; + } + + + match(input,QUOTE,FOLLOW_QUOTE_in_transition1038); + + match(input,PRESET,FOLLOW_PRESET_in_transition1040); + + match(input,EQUALS,FOLLOW_EQUALS_in_transition1042); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:728:69: ( '\"' '\"' | ( '\"' (pre= INT |pre1= ID ) ( ',' pre2= INT | ',' pre3= ID )* '\"' ) ) + int alt26=2; + int LA26_0 = input.LA(1); + + if ( (LA26_0==QUOTE) ) { + int LA26_1 = input.LA(2); + + if ( (LA26_1==QUOTE) ) { + alt26=1; + } + else if ( (LA26_1==ID||LA26_1==INT) ) { + alt26=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 26, 1, input); + + throw nvae; + + } + } + else { + NoViableAltException nvae = + new NoViableAltException("", 26, 0, input); + + throw nvae; + + } + switch (alt26) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:728:70: '\"' '\"' + { + match(input,QUOTE,FOLLOW_QUOTE_in_transition1045); + + match(input,QUOTE,FOLLOW_QUOTE_in_transition1047); + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:728:80: ( '\"' (pre= INT |pre1= ID ) ( ',' pre2= INT | ',' pre3= ID )* '\"' ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:728:80: ( '\"' (pre= INT |pre1= ID ) ( ',' pre2= INT | ',' pre3= ID )* '\"' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:728:81: '\"' (pre= INT |pre1= ID ) ( ',' pre2= INT | ',' pre3= ID )* '\"' + { + match(input,QUOTE,FOLLOW_QUOTE_in_transition1052); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:728:85: (pre= INT |pre1= ID ) + int alt24=2; + int LA24_0 = input.LA(1); + + if ( (LA24_0==INT) ) { + alt24=1; + } + else if ( (LA24_0==ID) ) { + alt24=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 24, 0, input); + + throw nvae; + + } + switch (alt24) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:728:86: pre= INT + { + pre=(Token)match(input,INT,FOLLOW_INT_in_transition1057); + + + //presetList.add(Integer.parseInt((pre!=null?pre.getText():null))); + if (pre!=null && initMarkedPlaces.contains(Integer.parseInt((pre!=null?pre.getText():null)))) + presetList.add(new Place("p"+(pre!=null?pre.getText():null), true)); + else + presetList.add(new Place("p"+(pre!=null?pre.getText():null), false)); + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:736:7: pre1= ID + { + pre1=(Token)match(input,ID,FOLLOW_ID_in_transition1077); + + + String pre1_tmp = (pre1!=null?pre1.getText():null); + if ((pre1!=null?pre1.getText():null).contains(".")) { + pre1_tmp = pre1_tmp.replace(".", "_"); + } + else { + pre1_tmp = (pre1!=null?pre1.getText():null); + } + result = ConstHashMap.get(pre1_tmp); + if(result == null){ + System.err.println("error on line " + pre1.getLine() + ": " + (pre1!=null?pre1.getText():null) + " is not a constant"); + System.exit(1); + } + //presetList.add(result); + if (initMarkedPlaces.contains(result)) + presetList.add(new Place("p"+result, true)); + else + presetList.add(new Place("p"+result, false)); + + + } + break; + + } + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:756:6: ( ',' pre2= INT | ',' pre3= ID )* + loop25: + do { + int alt25=3; + int LA25_0 = input.LA(1); + + if ( (LA25_0==COMMA) ) { + int LA25_2 = input.LA(2); + + if ( (LA25_2==INT) ) { + alt25=1; + } + else if ( (LA25_2==ID) ) { + alt25=2; + } + + + } + + + switch (alt25) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:756:8: ',' pre2= INT + { + match(input,COMMA,FOLLOW_COMMA_in_transition1093); + + pre2=(Token)match(input,INT,FOLLOW_INT_in_transition1097); + + + //presetList.add(Integer.parseInt((pre2!=null?pre2.getText():null))); + if (pre2!=null && initMarkedPlaces.contains(Integer.parseInt((pre2!=null?pre2.getText():null)))) + presetList.add(new Place("p"+(pre2!=null?pre2.getText():null), true)); + else + presetList.add(new Place("p"+(pre2!=null?pre2.getText():null), false)); + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:764:7: ',' pre3= ID + { + match(input,COMMA,FOLLOW_COMMA_in_transition1115); + + pre3=(Token)match(input,ID,FOLLOW_ID_in_transition1119); + + + String pre3_tmp = (pre3!=null?pre3.getText():null); + if ((pre3!=null?pre3.getText():null).contains(".")) { + pre3_tmp = pre3_tmp.replace(".", "_"); + } + else { + pre3_tmp = (pre3!=null?pre3.getText():null); + } + result = ConstHashMap.get(pre3_tmp); + if(result == null){ + System.err.println("error on line " + pre3.getLine() + ": " + (pre3!=null?pre3.getText():null) + " is not a constant"); + System.exit(1); + } + //presetList.add(result); + if (pre3!=null && initMarkedPlaces.contains(Integer.parseInt((pre3!=null?pre3.getText():null)))) + presetList.add(new Place("p"+result, true)); + else + presetList.add(new Place("p"+result, false)); + + + } + break; + + default : + break loop25; + } + } while (true); + + + match(input,QUOTE,FOLLOW_QUOTE_in_transition1134); + + } + + + } + break; + + } + + + match(input,POSTSET,FOLLOW_POSTSET_in_transition1138); + + match(input,EQUALS,FOLLOW_EQUALS_in_transition1140); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:784:27: ( '\"' '\"' | ( '\"' (post= INT |post1= ID ) ( ( ',' post2= INT ) | ( ',' post3= ID ) )* '\"' ) ) + int alt29=2; + int LA29_0 = input.LA(1); + + if ( (LA29_0==QUOTE) ) { + int LA29_1 = input.LA(2); + + if ( (LA29_1==QUOTE) ) { + alt29=1; + } + else if ( (LA29_1==ID||LA29_1==INT) ) { + alt29=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 29, 1, input); + + throw nvae; + + } + } + else { + NoViableAltException nvae = + new NoViableAltException("", 29, 0, input); + + throw nvae; + + } + switch (alt29) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:784:29: '\"' '\"' + { + match(input,QUOTE,FOLLOW_QUOTE_in_transition1144); + + match(input,QUOTE,FOLLOW_QUOTE_in_transition1146); + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:784:39: ( '\"' (post= INT |post1= ID ) ( ( ',' post2= INT ) | ( ',' post3= ID ) )* '\"' ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:784:39: ( '\"' (post= INT |post1= ID ) ( ( ',' post2= INT ) | ( ',' post3= ID ) )* '\"' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:784:40: '\"' (post= INT |post1= ID ) ( ( ',' post2= INT ) | ( ',' post3= ID ) )* '\"' + { + match(input,QUOTE,FOLLOW_QUOTE_in_transition1151); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:784:44: (post= INT |post1= ID ) + int alt27=2; + int LA27_0 = input.LA(1); + + if ( (LA27_0==INT) ) { + alt27=1; + } + else if ( (LA27_0==ID) ) { + alt27=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 27, 0, input); + + throw nvae; + + } + switch (alt27) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:784:46: post= INT + { + post=(Token)match(input,INT,FOLLOW_INT_in_transition1157); + + + //postsetList.add(Integer.parseInt((post!=null?post.getText():null))); + if (post!=null && initMarkedPlaces.contains(Integer.parseInt((post!=null?post.getText():null)))) + postsetList.add(new Place("p"+(post!=null?post.getText():null), true)); + else + postsetList.add(new Place("p"+(post!=null?post.getText():null), false)); + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:792:8: post1= ID + { + post1=(Token)match(input,ID,FOLLOW_ID_in_transition1177); + + + String post1_tmp = (post1!=null?post1.getText():null); + if ((post1!=null?post1.getText():null).contains(".")) { + post1_tmp = post1_tmp.replace(".", "_"); + } + else { + post1_tmp = (post1!=null?post1.getText():null); + } + result = ConstHashMap.get(post1_tmp); + if(result == null){ + System.err.println("error on line " + post1.getLine() + ": " + (post1!=null?post1.getText():null) + " is not a constant"); + System.exit(1); + } + //postsetList.add(result); + if (initMarkedPlaces.contains(result)) + postsetList.add(new Place("p"+result, true)); + else + postsetList.add(new Place("p"+result, false)); + + + } + break; + + } + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:813:6: ( ( ',' post2= INT ) | ( ',' post3= ID ) )* + loop28: + do { + int alt28=3; + int LA28_0 = input.LA(1); + + if ( (LA28_0==COMMA) ) { + int LA28_2 = input.LA(2); + + if ( (LA28_2==INT) ) { + alt28=1; + } + else if ( (LA28_2==ID) ) { + alt28=2; + } + + + } + + + switch (alt28) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:813:8: ( ',' post2= INT ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:813:8: ( ',' post2= INT ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:813:9: ',' post2= INT + { + match(input,COMMA,FOLLOW_COMMA_in_transition1202); + + post2=(Token)match(input,INT,FOLLOW_INT_in_transition1206); + + } + + + + //postsetList.add(Integer.parseInt((post2!=null?post2.getText():null))); + if (post2!=null && initMarkedPlaces.contains(Integer.parseInt((post2!=null?post2.getText():null)))) + postsetList.add(new Place("p"+(post2!=null?post2.getText():null), true)); + else + postsetList.add(new Place("p"+(post2!=null?post2.getText():null), false)); + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:821:8: ( ',' post3= ID ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:821:8: ( ',' post3= ID ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:821:9: ',' post3= ID + { + match(input,COMMA,FOLLOW_COMMA_in_transition1226); + + post3=(Token)match(input,ID,FOLLOW_ID_in_transition1229); + + } + + + + String post3_tmp = (post3!=null?post3.getText():null); + if ((post3!=null?post3.getText():null).contains(".")) { + post3_tmp = post3_tmp.replace(".", "_"); + } + else { + post3_tmp = (post3!=null?post3.getText():null); + } + result = ConstHashMap.get(post3_tmp); + if(result == null){ + System.err.println("error on line " + post3.getLine() + ": " + (post3!=null?post3.getText():null) + " is not a constant"); + System.exit(1); + } + // postsetList.add(result); + if (initMarkedPlaces.contains(result)) + postsetList.add(new Place("p"+result, true)); + else + postsetList.add(new Place("p"+result, false)); + + + } + break; + + default : + break loop28; + } + } while (true); + + + match(input,QUOTE,FOLLOW_QUOTE_in_transition1248); + + } + + + } + break; + + } + + + match(input,GREATER,FOLLOW_GREATER_in_transition1253); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:841:20: ( guard )? + int alt30=2; + switch ( input.LA(1) ) { + case BITWISE_NEGATION: + case FALSE: + case INT: + case MINUS: + case NEGATION: + case PLUS: + case TRUE: + { + alt30=1; + } + break; + case ID: + { + int LA30_2 = input.LA(2); + + if ( ((LA30_2 >= AND && LA30_2 <= BITWISE_LSHIFT)||(LA30_2 >= BITWISE_OR && LA30_2 <= BITWISE_XOR)||LA30_2==DIV||LA30_2==EQUIV||(LA30_2 >= GREATER && LA30_2 <= GREATER_EQUAL)||LA30_2==IMPLICATION||(LA30_2 >= LESS && LA30_2 <= LESS_EQUAL)||LA30_2==MINUS||(LA30_2 >= NOT_EQUIV && LA30_2 <= OR)||LA30_2==PLUS||LA30_2==QMARK||LA30_2==SEMICOLON||LA30_2==TIMES) ) { + alt30=1; + } + } + break; + case LPAREN: + { + int LA30_3 = input.LA(2); + + if ( (LA30_3==INT) ) { + int LA30_5 = input.LA(3); + + if ( ((LA30_5 >= AND && LA30_5 <= BITWISE_LSHIFT)||(LA30_5 >= BITWISE_OR && LA30_5 <= BITWISE_XOR)||LA30_5==DIV||LA30_5==EQUIV||(LA30_5 >= GREATER && LA30_5 <= GREATER_EQUAL)||LA30_5==IMPLICATION||(LA30_5 >= LESS && LA30_5 <= LESS_EQUAL)||LA30_5==MINUS||(LA30_5 >= NOT_EQUIV && LA30_5 <= OR)||LA30_5==PLUS||LA30_5==QMARK||LA30_5==RPAREN||LA30_5==TIMES) ) { + alt30=1; + } + } + else if ( (LA30_3==BITWISE_NEGATION||LA30_3==FALSE||LA30_3==ID||LA30_3==LPAREN||LA30_3==MINUS||LA30_3==NEGATION||LA30_3==PLUS||LA30_3==TRUE) ) { + alt30=1; + } + } + break; + } + + switch (alt30) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:841:21: guard + { + pushFollow(FOLLOW_guard_in_transition1256); + guard6=guard(); + + state._fsp--; + + + + guardExpr = guard6; + + + } + break; + + } + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:845:9: ( delay )? + int alt31=2; + int LA31_0 = input.LA(1); + + if ( (LA31_0==LPAREN) ) { + alt31=1; + } + switch (alt31) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:845:10: delay + { + pushFollow(FOLLOW_delay_in_transition1276); + delay7=delay(); + + state._fsp--; + + + + // TODO: ignored delay for untimed models + delayLB = (delay7!=null?delay7.delayLB:0); + delayUB = (delay7!=null?delay7.delayUB:0); + + + } + break; + + } + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:851:9: ( ( assertion ) | ( assignment ) )* + loop32: + do { + int alt32=3; + int LA32_0 = input.LA(1); + + if ( (LA32_0==59) ) { + alt32=1; + } + else if ( (LA32_0==ID) ) { + alt32=2; + } + + + switch (alt32) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:851:10: ( assertion ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:851:10: ( assertion ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:851:11: assertion + { + pushFollow(FOLLOW_assertion_in_transition1297); + assertion8=assertion(); + + state._fsp--; + + + + // TODO: ignored assertions temporarily + if(assertion8 != null){ + assertionList.add(assertion8); + } + + + } + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:858:10: ( assignment ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:858:10: ( assignment ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:858:11: assignment + { + pushFollow(FOLLOW_assignment_in_transition1317); + assignment9=assignment(); + + state._fsp--; + + + + assignmentList.putAll(assignment9); + + + } + + + } + break; + + default : + break loop32; + } + } while (true); + + + match(input,LESS,FOLLOW_LESS_in_transition1336); + + match(input,DIV,FOLLOW_DIV_in_transition1338); + + match(input,TRANSITION,FOLLOW_TRANSITION_in_transition1340); + + match(input,GREATER,FOLLOW_GREATER_in_transition1342); + + + // create new lpn transitions and add assertions + // lpnTran = new LPNTran((lbl!=null?lbl.getText():null), TransitionIndex++, presetList, postsetList, guardExpr, assignmentList, delayLB, delayUB, local); + lpnTran = new Transition(); + lpnTran.setName("t" + (lbl!=null?lbl.getText():null)); + lpnTran.setIndex(TransitionIndex++); + for (Place p: presetList) { + lpnTran.addPreset(p); + } + for (Place p: postsetList) { + lpnTran.addPostset(p); + } + lpnTran.addEnablingWithoutLPN(guardExpr); + for (String var : assignmentList.keySet()) { + lpnTran.addIntAssign(var, assignmentList.get(var)); + } + + // TODO: Add assertionList to the new lpn transition + // if(assertionList.size() > 0){ + // lpnTran.addAllAssertions(assertionList); + // } + + // add non-local transition to associated LPNs + for(String var : assignmentList.keySet()){ + if(Outputs.contains(var)){ + // local is determined by isLocal() in Transition.java + local = false; + // if(GlobalInputMap.containsKey(var)){ + // for(LhpnFile lpn : GlobalInputMap.get(var)){ + // lpn.addInputTran(lpnTran); + // // dstLpn is added by setDstLpnList in Transition.java + // lpnTran.addDstLpn(lpn); + // } + // } + } + + // map lpn transition with output and potential outuput variables + if(GlobalTranMap.containsKey(var)){ + GlobalTranMap.get(var).add(lpnTran); + System.out.println("Add "+ lpnTran.getLabel() + " to variable " + var); + } + else{ + List tranList = new ArrayList(); + tranList.add(lpnTran); + GlobalTranMap.put(var, tranList); + System.out.println("Create tranList for variable " + var + ", and add " + lpnTran.getLabel() + " to it."); + + } + } + + // lpnTran.setLocal(local); + if(local == false){ + outputTranList.add(lpnTran); + } + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return lpnTran; + } + // $ANTLR end "transition" + + + + // $ANTLR start "assertion" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:920:1: assertion returns [ExprTree booleanExpr] : 'assert' '(' expression ')' ';' ; + public final ExprTree assertion() throws RecognitionException { + ExprTree booleanExpr = null; + + + ExprTree expression10 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:921:2: ( 'assert' '(' expression ')' ';' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:921:4: 'assert' '(' expression ')' ';' + { + booleanExpr = null;// TODO: assertion + + + match(input,59,FOLLOW_59_in_assertion1377); + + match(input,LPAREN,FOLLOW_LPAREN_in_assertion1379); + + pushFollow(FOLLOW_expression_in_assertion1381); + expression10=expression(); + + state._fsp--; + + + match(input,RPAREN,FOLLOW_RPAREN_in_assertion1383); + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_assertion1385); + + + //booleanExpr = new Expression(expression10); + booleanExpr = new ExprTree(expression10); + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return booleanExpr; + } + // $ANTLR end "assertion" + + + + // $ANTLR start "guard" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:930:1: guard returns [ExprTree expr] : expression ';' ; + public final ExprTree guard() throws RecognitionException { + ExprTree expr = null; + + + ExprTree expression11 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:931:5: ( expression ';' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:931:9: expression ';' + { + pushFollow(FOLLOW_expression_in_guard1411); + expression11=expression(); + + state._fsp--; + + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_guard1413); + + + //expr = new Expression(expression11); + expr = new ExprTree(expression11); + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return expr; + } + // $ANTLR end "guard" + + + public static class delay_return extends ParserRuleReturnScope { + public int delayLB; + public int delayUB; + }; + + + // $ANTLR start "delay" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:938:1: delay returns [int delayLB, int delayUB] : '(' lb= INT ',' (ub= INT | 'inf' ) ')' ';' ; + public final PlatuGrammarParser.delay_return delay() throws RecognitionException { + PlatuGrammarParser.delay_return retval = new PlatuGrammarParser.delay_return(); + retval.start = input.LT(1); + + + Token lb=null; + Token ub=null; + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:939:5: ( '(' lb= INT ',' (ub= INT | 'inf' ) ')' ';' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:939:8: '(' lb= INT ',' (ub= INT | 'inf' ) ')' ';' + { + match(input,LPAREN,FOLLOW_LPAREN_in_delay1447); + + lb=(Token)match(input,INT,FOLLOW_INT_in_delay1451); + + + retval.delayLB = Integer.parseInt((lb!=null?lb.getText():null)); + + + match(input,COMMA,FOLLOW_COMMA_in_delay1465); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:943:8: (ub= INT | 'inf' ) + int alt33=2; + int LA33_0 = input.LA(1); + + if ( (LA33_0==INT) ) { + alt33=1; + } + else if ( (LA33_0==61) ) { + alt33=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 33, 0, input); + + throw nvae; + + } + switch (alt33) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:943:9: ub= INT + { + ub=(Token)match(input,INT,FOLLOW_INT_in_delay1470); + + + retval.delayUB = Integer.parseInt((ub!=null?ub.getText():null)); + // make sure delays are >= 0 and upper bound is >= lower bound + if(retval.delayLB < 0){ + System.err.println("error on line " + lb.getLine() + ": lower bound " + retval.delayLB + " must be >= 0"); + System.exit(1); + } + else if(retval.delayLB == INFINITY){ + System.err.println("error on line " + ub.getLine() + ": lower bound " + retval.delayUB + " must be a non-negative finite number"); + System.exit(1); + } + else if(retval.delayUB < retval.delayLB){ + System.err.println("error on line " + ub.getLine() + ": upper bound " + retval.delayUB + " < lower bound " + retval.delayLB); + System.exit(1); + } + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:960:6: 'inf' + { + match(input,61,FOLLOW_61_in_delay1485); + + + retval.delayUB = INFINITY; + + + } + break; + + } + + + match(input,RPAREN,FOLLOW_RPAREN_in_delay1498); + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_delay1500); + + } + + retval.stop = input.LT(-1); + + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "delay" + + + + // $ANTLR start "assignment" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:967:1: assignment returns [HashMap assign] : ( (var= ID '=' expression ';' ) | (var2= ID ( '[' ( INT | ID ) ']' )+ '=' expression ';' ) ); + public final HashMap assignment() throws RecognitionException { + HashMap assign = null; + + + Token var=null; + Token var2=null; + ExprTree expression12 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:968:5: ( (var= ID '=' expression ';' ) | (var2= ID ( '[' ( INT | ID ) ']' )+ '=' expression ';' ) ) + int alt35=2; + int LA35_0 = input.LA(1); + + if ( (LA35_0==ID) ) { + int LA35_1 = input.LA(2); + + if ( (LA35_1==EQUALS) ) { + alt35=1; + } + else if ( (LA35_1==57) ) { + alt35=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 35, 1, input); + + throw nvae; + + } + } + else { + NoViableAltException nvae = + new NoViableAltException("", 35, 0, input); + + throw nvae; + + } + switch (alt35) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:968:9: (var= ID '=' expression ';' ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:968:9: (var= ID '=' expression ';' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:968:10: var= ID '=' expression ';' + { + var=(Token)match(input,ID,FOLLOW_ID_in_assignment1526); + + match(input,EQUALS,FOLLOW_EQUALS_in_assignment1528); + + + String var_tmp = (var!=null?var.getText():null); + if ((var!=null?var.getText():null).contains(".")) { + var_tmp = var_tmp.replace(".", "_"); + } + else { + var_tmp = (var!=null?var.getText():null); + } + // make sure only global, internal and output variables are assigned + if(GlobalConstHashMap.containsKey(var_tmp)){ + System.err.println("error on line " + var.getLine() + ": global constant " + (var!=null?var.getText():null) + " cannot be assigned"); + System.exit(1); + } + else if(ConstHashMap.containsKey(var_tmp)){ + System.err.println("error on line " + var.getLine() + ": constant " + (var!=null?var.getText():null) + " cannot be assigned"); + System.exit(1); + } + else if(!Outputs.contains(var_tmp) && !Internals.contains(var_tmp)){ + System.err.println("error on line " + var.getLine() + ": input variable " + (var!=null?var.getText():null) + " cannot be assigned"); + System.exit(1); + } + + + pushFollow(FOLLOW_expression_in_assignment1544); + expression12=expression(); + + state._fsp--; + + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_assignment1546); + + + Integer varCount = VarCountMap.get(var_tmp); + if(varCount != null){ + VarCountMap.put(var_tmp, ++varCount); + } + + // Expression expr = new Expression(expression12); + // assign = new VarExpr(VarNodeMap.get((var!=null?var.getText():null)), expr); + + ExprTree expr = new ExprTree(expression12); + assign = new HashMap(); + assign.put(var_tmp, expr); + + + } + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1006:10: (var2= ID ( '[' ( INT | ID ) ']' )+ '=' expression ';' ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1006:10: (var2= ID ( '[' ( INT | ID ) ']' )+ '=' expression ';' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1006:11: var2= ID ( '[' ( INT | ID ) ']' )+ '=' expression ';' + { + var2=(Token)match(input,ID,FOLLOW_ID_in_assignment1575); + + + List indexList = new ArrayList(); + + + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1011:6: ( '[' ( INT | ID ) ']' )+ + int cnt34=0; + loop34: + do { + int alt34=2; + int LA34_0 = input.LA(1); + + if ( (LA34_0==57) ) { + alt34=1; + } + + + switch (alt34) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1011:7: '[' ( INT | ID ) ']' + { + match(input,57,FOLLOW_57_in_assignment1592); + + if ( input.LA(1)==ID||input.LA(1)==INT ) { + input.consume(); + state.errorRecovery=false; + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + throw mse; + } + + + match(input,58,FOLLOW_58_in_assignment1602); + + } + break; + + default : + if ( cnt34 >= 1 ) break loop34; + EarlyExitException eee = + new EarlyExitException(34, input); + throw eee; + } + cnt34++; + } while (true); + + + match(input,EQUALS,FOLLOW_EQUALS_in_assignment1606); + + pushFollow(FOLLOW_expression_in_assignment1608); + expression(); + + state._fsp--; + + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_assignment1610); + + + + + } + + + } + break; + + } + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return assign; + } + // $ANTLR end "assignment" + + + + // $ANTLR start "term" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1018:1: term returns [ExprTree expr] : ( ID | LPAREN expression RPAREN | INT | TRUE | FALSE ); + public final ExprTree term() throws RecognitionException { + ExprTree expr = null; + + + Token ID13=null; + Token INT15=null; + ExprTree expression14 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1019:5: ( ID | LPAREN expression RPAREN | INT | TRUE | FALSE ) + int alt36=5; + switch ( input.LA(1) ) { + case ID: + { + alt36=1; + } + break; + case LPAREN: + { + alt36=2; + } + break; + case INT: + { + alt36=3; + } + break; + case TRUE: + { + alt36=4; + } + break; + case FALSE: + { + alt36=5; + } + break; + default: + NoViableAltException nvae = + new NoViableAltException("", 36, 0, input); + + throw nvae; + + } + + switch (alt36) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1019:9: ID + { + ID13=(Token)match(input,ID,FOLLOW_ID_in_term1654); + + + String ID_tmp = (ID13!=null?ID13.getText():null); + if ((ID13!=null?ID13.getText():null).contains(".")) { + ID_tmp = ID_tmp.replace(".", "_"); + } + else { + ID_tmp = (ID13!=null?ID13.getText():null); + } + if(ConstHashMap.containsKey(ID_tmp)){ + //expr = new ConstNode((ID13!=null?ID13.getText():null), ConstHashMap.get((ID13!=null?ID13.getText():null))); + expr = new ExprTree(ConstHashMap.get(ID_tmp)+""); + } + else if(GlobalConstHashMap.containsKey(ID_tmp)){ + //expr = new ConstNode((ID13!=null?ID13.getText():null), GlobalConstHashMap.get((ID13!=null?ID13.getText():null))); + expr = new ExprTree(GlobalConstHashMap.get(ID_tmp)+""); + } + else if(StatevectorMap.containsKey(ID_tmp)){ + //expr = VarNodeMap.get((ID13!=null?ID13.getText():null)); + expr = VarNodeMap.get(ID_tmp); + } + else{ // identify new input variable + // // create expression + // expr = new platu.lpn.io.expression.VarNode((ID13!=null?ID13.getText():null)); + + // label as input and initialize to 0 + StatevectorMap.put(ID_tmp, 0); + System.out.println("label (" + ID_tmp + ") as input and initialize to 0. Added to Inputs."); + Inputs.add(ID_tmp); + for (String input : Inputs) { + System.out.println("@3: input = " + input); + } + + // identify new input variable + // create expression + ExprTree newVarNode = new ExprTree(ID_tmp); + newVarNode.setIntegerSignals(StatevectorMap.keySet()); + expr = newVarNode.getExprTree(); + VarNodeMap.put(ID_tmp, newVarNode); + + // int index = VariableIndex++; + // VarIndexMap.insert((ID13!=null?ID13.getText():null), index); + // VarNode newVarNode = new VarNode((ID13!=null?ID13.getText():null), index); + // VarNodeMap.put((ID13!=null?ID13.getText():null), newVarNode); + // expr = newVarNode; + + // if associated output variable has not been defined insert with null value, + // otherwise get output variable and relabel from internal to output, + // get output value and initialize input statevector, label lpn transitions associated with output as non-local + // and add to current lpn's inputTranList + if(!GlobalInterfaceMap.containsKey(ID_tmp)){ + GlobalInterfaceMap.put(ID_tmp, null); + System.out.println("@ term, Added entry (" + ID_tmp + "null) to GlobalInterfaceMap"); + } + else{ + Integer value = GlobalInterfaceMap.get(ID_tmp); + if(value != null){ + StatevectorMap.put(ID_tmp, value); + LPN outputLPN = GlobalOutputMap.get(ID_tmp); + if(outputLPN.getAllInternals().keySet().contains(ID_tmp)){ + outputLPN.getAllInternals().remove(ID_tmp); + // for (String varID : outputLPN.getAllInternals().keySet()) { + // System.out.println("@term-outputLPN: internal var " + varID + " is in LPN " + outputLPN.getLabel()); + // } + outputLPN.addOutput(ID_tmp, "integer", value+""); + //System.out.println("@term : Removed internal variable " + ID_tmp); + //System.out.println("@term : Added output variable " + ID_tmp + " to LPN " + outputLPN.getLabel()); + } + for(Transition tran : GlobalTranMap.get(ID_tmp)){ + //tran.setLocalFlag(false); + //outputLPN.addOutputTran(tran); + outputLPN.addTransition(tran); + System.out.println("@term : Added transition " + tran.getLabel() + " to LPN " + outputLPN.getLabel()); + inputTranList.add(tran); + System.out.println("@term : Added transition " + tran.getLabel() + " to inputTranList."); + System.out.println("inputTranList : "); + for (Transition t : inputTranList) { + System.out.println("Transition: " + t.getLabel()); + } + System.out.println("~~~~~~~~~~~~~"); + } + } + } + } + + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1104:9: LPAREN expression RPAREN + { + match(input,LPAREN,FOLLOW_LPAREN_in_term1672); + + pushFollow(FOLLOW_expression_in_term1674); + expression14=expression(); + + state._fsp--; + + + match(input,RPAREN,FOLLOW_RPAREN_in_term1676); + + expr = expression14; + + } + break; + case 3 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1105:9: INT + { + INT15=(Token)match(input,INT,FOLLOW_INT_in_term1688); + + //{expr = new ConstNode("name", Integer.parseInt((INT15!=null?INT15.getText():null)));} + ExprTree tree = new ExprTree(Integer.parseInt((INT15!=null?INT15.getText():null))+""); + expr = tree.getExprTree(); + + + } + break; + case 4 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1109:9: TRUE + { + match(input,TRUE,FOLLOW_TRUE_in_term1701); + + + ExprTree tree = new ExprTree("true"); + expr = tree.getExprTree(); + + + } + break; + case 5 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1113:9: FALSE + { + match(input,FALSE,FOLLOW_FALSE_in_term1713); + + + ExprTree tree = new ExprTree("false"); + expr = tree.getExprTree(); + + + } + break; + + } + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return expr; + } + // $ANTLR end "term" + + + + // $ANTLR start "unary" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1123:1: unary returns [ExprTree expr] : ( '+' | ( '-' ) )* term ; + public final ExprTree unary() throws RecognitionException { + ExprTree expr = null; + + + ExprTree term16 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1124:5: ( ( '+' | ( '-' ) )* term ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1124:9: ( '+' | ( '-' ) )* term + { + boolean positive = true; + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1125:6: ( '+' | ( '-' ) )* + loop37: + do { + int alt37=3; + int LA37_0 = input.LA(1); + + if ( (LA37_0==PLUS) ) { + alt37=1; + } + else if ( (LA37_0==MINUS) ) { + alt37=2; + } + + + switch (alt37) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1125:7: '+' + { + match(input,PLUS,FOLLOW_PLUS_in_unary1754); + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1125:13: ( '-' ) + { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1125:13: ( '-' ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1125:14: '-' + { + match(input,MINUS,FOLLOW_MINUS_in_unary1759); + + if(positive){ positive = false;} else {positive = true;} + + } + + + } + break; + + default : + break loop37; + } + } while (true); + + + pushFollow(FOLLOW_term_in_unary1766); + term16=term(); + + state._fsp--; + + + + if(!positive){ + //expr = new MinNode(term16); + // TODO: Correct ExprTree for unary? + expr = new ExprTree(term16, null, "U-", 'a'); + } + else{ + expr = term16; + } + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return expr; + } + // $ANTLR end "unary" + + + + // $ANTLR start "bitwiseNegation" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1138:1: bitwiseNegation returns [ExprTree expr] : ( '~' )* unary ; + public final ExprTree bitwiseNegation() throws RecognitionException { + ExprTree expr = null; + + + ExprTree unary17 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1139:2: ( ( '~' )* unary ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1139:5: ( '~' )* unary + { + boolean neg = false; + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1140:3: ( '~' )* + loop38: + do { + int alt38=2; + int LA38_0 = input.LA(1); + + if ( (LA38_0==BITWISE_NEGATION) ) { + alt38=1; + } + + + switch (alt38) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1140:4: '~' + { + match(input,BITWISE_NEGATION,FOLLOW_BITWISE_NEGATION_in_bitwiseNegation1798); + + if(neg){neg = false;} else{neg = true;} + + } + break; + + default : + break loop38; + } + } while (true); + + + pushFollow(FOLLOW_unary_in_bitwiseNegation1804); + unary17=unary(); + + state._fsp--; + + + + if(neg){ + //expr = new BitNegNode(unary17); + expr = new ExprTree(null, unary17, "~", 'l'); + } + else{ + expr = unary17; + } + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return expr; + } + // $ANTLR end "bitwiseNegation" + + + + // $ANTLR start "negation" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1152:1: negation returns [ExprTree expr] : ( '!' )* bitwiseNegation ; + public final ExprTree negation() throws RecognitionException { + ExprTree expr = null; + + + ExprTree bitwiseNegation18 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1153:2: ( ( '!' )* bitwiseNegation ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1153:4: ( '!' )* bitwiseNegation + { + boolean neg = false; + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1154:3: ( '!' )* + loop39: + do { + int alt39=2; + int LA39_0 = input.LA(1); + + if ( (LA39_0==NEGATION) ) { + alt39=1; + } + + + switch (alt39) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1154:4: '!' + { + match(input,NEGATION,FOLLOW_NEGATION_in_negation1830); + + if(neg){neg = false;} else{neg = true;} + + } + break; + + default : + break loop39; + } + } while (true); + + + pushFollow(FOLLOW_bitwiseNegation_in_negation1836); + bitwiseNegation18=bitwiseNegation(); + + state._fsp--; + + + + if(neg){ + //expr = new NegNode(bitwiseNegation18); + // TODO: Correct translation of negation? + expr = new ExprTree(null, bitwiseNegation18, "~", 'l'); + } + else{ + expr = bitwiseNegation18; + } + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return expr; + } + // $ANTLR end "negation" + + + + // $ANTLR start "mult" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1167:1: mult returns [ExprTree expr] : op1= negation ( '*' op2= negation | '/' op2= negation )* ; + public final ExprTree mult() throws RecognitionException { + ExprTree expr = null; + + + ExprTree op1 =null; + + ExprTree op2 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1168:5: (op1= negation ( '*' op2= negation | '/' op2= negation )* ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1168:9: op1= negation ( '*' op2= negation | '/' op2= negation )* + { + pushFollow(FOLLOW_negation_in_mult1865); + op1=negation(); + + state._fsp--; + + + expr = op1; + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1169:6: ( '*' op2= negation | '/' op2= negation )* + loop40: + do { + int alt40=3; + int LA40_0 = input.LA(1); + + if ( (LA40_0==TIMES) ) { + alt40=1; + } + else if ( (LA40_0==DIV) ) { + alt40=2; + } + + + switch (alt40) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1169:8: '*' op2= negation + { + match(input,TIMES,FOLLOW_TIMES_in_mult1877); + + pushFollow(FOLLOW_negation_in_mult1881); + op2=negation(); + + state._fsp--; + + + expr = new ExprTree(expr, op2, "*", 'a'); + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1170:8: '/' op2= negation + { + match(input,DIV,FOLLOW_DIV_in_mult1892); + + pushFollow(FOLLOW_negation_in_mult1896); + op2=negation(); + + state._fsp--; + + + expr = new ExprTree(expr, op2, "/", 'a'); + + } + break; + + default : + break loop40; + } + } while (true); + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return expr; + } + // $ANTLR end "mult" + + + public static class add_return extends ParserRuleReturnScope { + public ExprTree expr; + }; + + + // $ANTLR start "add" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1176:1: add returns [ExprTree expr] : op1= mult ( '+' op2= mult | '-' op2= mult )* ; + public final PlatuGrammarParser.add_return add() throws RecognitionException { + PlatuGrammarParser.add_return retval = new PlatuGrammarParser.add_return(); + retval.start = input.LT(1); + + + ExprTree op1 =null; + + ExprTree op2 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1177:5: (op1= mult ( '+' op2= mult | '-' op2= mult )* ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1177:9: op1= mult ( '+' op2= mult | '-' op2= mult )* + { + pushFollow(FOLLOW_mult_in_add1948); + op1=mult(); + + state._fsp--; + + + retval.expr = op1; + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1178:6: ( '+' op2= mult | '-' op2= mult )* + loop41: + do { + int alt41=3; + int LA41_0 = input.LA(1); + + if ( (LA41_0==PLUS) ) { + alt41=1; + } + else if ( (LA41_0==MINUS) ) { + alt41=2; + } + + + switch (alt41) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1178:8: '+' op2= mult + { + match(input,PLUS,FOLLOW_PLUS_in_add1959); + + pushFollow(FOLLOW_mult_in_add1963); + op2=mult(); + + state._fsp--; + + + retval.expr = new ExprTree(retval.expr, op2, "+", 'a'); + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1179:9: '-' op2= mult + { + match(input,MINUS,FOLLOW_MINUS_in_add1975); + + pushFollow(FOLLOW_mult_in_add1979); + op2=mult(); + + state._fsp--; + + + retval.expr = new ExprTree(retval.expr, op2, "-", 'a'); + + } + break; + + default : + break loop41; + } + } while (true); + + + } + + retval.stop = input.LT(-1); + + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "add" + + + + // $ANTLR start "shift" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1183:1: shift returns [ExprTree expr] : op1= add ( '<<' op2= add | '>>' op2= add )* ; + public final ExprTree shift() throws RecognitionException { + ExprTree expr = null; + + + PlatuGrammarParser.add_return op1 =null; + + PlatuGrammarParser.add_return op2 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1184:5: (op1= add ( '<<' op2= add | '>>' op2= add )* ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1184:9: op1= add ( '<<' op2= add | '>>' op2= add )* + { + pushFollow(FOLLOW_add_in_shift2018); + op1=add(); + + state._fsp--; + + + expr = (op1!=null?op1.expr:null); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1185:7: ( '<<' op2= add | '>>' op2= add )* + loop42: + do { + int alt42=3; + int LA42_0 = input.LA(1); + + if ( (LA42_0==BITWISE_LSHIFT) ) { + alt42=1; + } + else if ( (LA42_0==BITWISE_RSHIFT) ) { + alt42=2; + } + + + switch (alt42) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1185:9: '<<' op2= add + { + match(input,BITWISE_LSHIFT,FOLLOW_BITWISE_LSHIFT_in_shift2030); + + pushFollow(FOLLOW_add_in_shift2034); + op2=add(); + + state._fsp--; + + + expr = new ExprTree(new ExprTree("int(" + (op1!=null?input.toString(op1.start,op1.stop):null) + ")"), new ExprTree(new ExprTree("2"), (op2!=null?op2.expr:null), "^", 'a'), "*", 'a'); + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1186:11: '>>' op2= add + { + match(input,BITWISE_RSHIFT,FOLLOW_BITWISE_RSHIFT_in_shift2048); + + pushFollow(FOLLOW_add_in_shift2052); + op2=add(); + + state._fsp--; + + + expr = new ExprTree(new ExprTree("int(" + (op1!=null?input.toString(op1.start,op1.stop):null) + ")"), new ExprTree(new ExprTree("2"), (op2!=null?op2.expr:null), "^", 'a'), "/", 'a'); + + } + break; + + default : + break loop42; + } + } while (true); + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return expr; + } + // $ANTLR end "shift" + + + + // $ANTLR start "relation" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1193:1: relation returns [ExprTree expr] : op1= shift ( '<' op2= shift | '<=' op2= shift | '>=' op2= shift | '>' op2= shift )* ; + public final ExprTree relation() throws RecognitionException { + ExprTree expr = null; + + + ExprTree op1 =null; + + ExprTree op2 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1194:5: (op1= shift ( '<' op2= shift | '<=' op2= shift | '>=' op2= shift | '>' op2= shift )* ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1194:9: op1= shift ( '<' op2= shift | '<=' op2= shift | '>=' op2= shift | '>' op2= shift )* + { + pushFollow(FOLLOW_shift_in_relation2091); + op1=shift(); + + state._fsp--; + + + expr = op1; + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1195:6: ( '<' op2= shift | '<=' op2= shift | '>=' op2= shift | '>' op2= shift )* + loop43: + do { + int alt43=5; + switch ( input.LA(1) ) { + case LESS: + { + alt43=1; + } + break; + case LESS_EQUAL: + { + alt43=2; + } + break; + case GREATER_EQUAL: + { + alt43=3; + } + break; + case GREATER: + { + alt43=4; + } + break; + + } + + switch (alt43) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1195:8: '<' op2= shift + { + match(input,LESS,FOLLOW_LESS_in_relation2102); + + pushFollow(FOLLOW_shift_in_relation2106); + op2=shift(); + + state._fsp--; + + + expr = new ExprTree(expr, op2, "<", 'r'); + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1196:9: '<=' op2= shift + { + match(input,LESS_EQUAL,FOLLOW_LESS_EQUAL_in_relation2118); + + pushFollow(FOLLOW_shift_in_relation2122); + op2=shift(); + + state._fsp--; + + + expr = new ExprTree(expr, op2, "<=", 'r'); + + } + break; + case 3 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1197:9: '>=' op2= shift + { + match(input,GREATER_EQUAL,FOLLOW_GREATER_EQUAL_in_relation2134); + + pushFollow(FOLLOW_shift_in_relation2138); + op2=shift(); + + state._fsp--; + + + expr = new ExprTree(expr, op2, ">=", 'r'); + + } + break; + case 4 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1198:9: '>' op2= shift + { + match(input,GREATER,FOLLOW_GREATER_in_relation2150); + + pushFollow(FOLLOW_shift_in_relation2154); + op2=shift(); + + state._fsp--; + + + expr = new ExprTree(expr, op2, ">", 'r'); + + } + break; + + default : + break loop43; + } + } while (true); + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return expr; + } + // $ANTLR end "relation" + + + + // $ANTLR start "equivalence" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1202:1: equivalence returns [ExprTree expr] : op1= relation ( '==' op2= relation | '!=' op2= relation )* ; + public final ExprTree equivalence() throws RecognitionException { + ExprTree expr = null; + + + ExprTree op1 =null; + + ExprTree op2 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1203:5: (op1= relation ( '==' op2= relation | '!=' op2= relation )* ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1203:9: op1= relation ( '==' op2= relation | '!=' op2= relation )* + { + pushFollow(FOLLOW_relation_in_equivalence2194); + op1=relation(); + + state._fsp--; + + + expr = op1; + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1204:6: ( '==' op2= relation | '!=' op2= relation )* + loop44: + do { + int alt44=3; + int LA44_0 = input.LA(1); + + if ( (LA44_0==EQUIV) ) { + alt44=1; + } + else if ( (LA44_0==NOT_EQUIV) ) { + alt44=2; + } + + + switch (alt44) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1204:8: '==' op2= relation + { + match(input,EQUIV,FOLLOW_EQUIV_in_equivalence2205); + + pushFollow(FOLLOW_relation_in_equivalence2209); + op2=relation(); + + state._fsp--; + + + expr = new ExprTree(expr, op2, "=", 'r'); + + } + break; + case 2 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1206:8: '!=' op2= relation + { + match(input,NOT_EQUIV,FOLLOW_NOT_EQUIV_in_equivalence2226); + + pushFollow(FOLLOW_relation_in_equivalence2230); + op2=relation(); + + state._fsp--; + + + expr = new ExprTree(new ExprTree(expr, op2, "=", 'r'), null, "~", 'l'); + + } + break; + + default : + break loop44; + } + } while (true); + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return expr; + } + // $ANTLR end "equivalence" + + + + // $ANTLR start "bitwiseAnd" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1210:1: bitwiseAnd returns [ExprTree expr] : op1= equivalence ( '&' op2= equivalence )* ; + public final ExprTree bitwiseAnd() throws RecognitionException { + ExprTree expr = null; + + + ExprTree op1 =null; + + ExprTree op2 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1211:5: (op1= equivalence ( '&' op2= equivalence )* ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1211:9: op1= equivalence ( '&' op2= equivalence )* + { + pushFollow(FOLLOW_equivalence_in_bitwiseAnd2269); + op1=equivalence(); + + state._fsp--; + + + expr = op1; + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1212:6: ( '&' op2= equivalence )* + loop45: + do { + int alt45=2; + int LA45_0 = input.LA(1); + + if ( (LA45_0==BITWISE_AND) ) { + alt45=1; + } + + + switch (alt45) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1212:8: '&' op2= equivalence + { + match(input,BITWISE_AND,FOLLOW_BITWISE_AND_in_bitwiseAnd2281); + + pushFollow(FOLLOW_equivalence_in_bitwiseAnd2285); + op2=equivalence(); + + state._fsp--; + + + expr = new ExprTree(expr, op2, "&", 'w'); + + } + break; + + default : + break loop45; + } + } while (true); + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return expr; + } + // $ANTLR end "bitwiseAnd" + + + + // $ANTLR start "bitwiseXor" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1216:1: bitwiseXor returns [ExprTree expr] : op1= bitwiseAnd ( '^' op2= bitwiseAnd )* ; + public final ExprTree bitwiseXor() throws RecognitionException { + ExprTree expr = null; + + + ExprTree op1 =null; + + ExprTree op2 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1217:5: (op1= bitwiseAnd ( '^' op2= bitwiseAnd )* ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1217:9: op1= bitwiseAnd ( '^' op2= bitwiseAnd )* + { + pushFollow(FOLLOW_bitwiseAnd_in_bitwiseXor2324); + op1=bitwiseAnd(); + + state._fsp--; + + + expr = op1; + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1218:6: ( '^' op2= bitwiseAnd )* + loop46: + do { + int alt46=2; + int LA46_0 = input.LA(1); + + if ( (LA46_0==BITWISE_XOR) ) { + alt46=1; + } + + + switch (alt46) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1218:8: '^' op2= bitwiseAnd + { + match(input,BITWISE_XOR,FOLLOW_BITWISE_XOR_in_bitwiseXor2335); + + pushFollow(FOLLOW_bitwiseAnd_in_bitwiseXor2339); + op2=bitwiseAnd(); + + state._fsp--; + + + expr = new ExprTree(expr, op2, "X", 'w'); + + } + break; + + default : + break loop46; + } + } while (true); + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return expr; + } + // $ANTLR end "bitwiseXor" + + + + // $ANTLR start "bitwiseOr" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1222:1: bitwiseOr returns [ExprTree expr] : op1= bitwiseXor ( '|' op2= bitwiseXor )* ; + public final ExprTree bitwiseOr() throws RecognitionException { + ExprTree expr = null; + + + ExprTree op1 =null; + + ExprTree op2 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1223:5: (op1= bitwiseXor ( '|' op2= bitwiseXor )* ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1223:9: op1= bitwiseXor ( '|' op2= bitwiseXor )* + { + pushFollow(FOLLOW_bitwiseXor_in_bitwiseOr2378); + op1=bitwiseXor(); + + state._fsp--; + + + expr = op1; + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1224:6: ( '|' op2= bitwiseXor )* + loop47: + do { + int alt47=2; + int LA47_0 = input.LA(1); + + if ( (LA47_0==BITWISE_OR) ) { + alt47=1; + } + + + switch (alt47) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1224:8: '|' op2= bitwiseXor + { + match(input,BITWISE_OR,FOLLOW_BITWISE_OR_in_bitwiseOr2389); + + pushFollow(FOLLOW_bitwiseXor_in_bitwiseOr2393); + op2=bitwiseXor(); + + state._fsp--; + + + expr = new ExprTree(expr, op2, "|", 'w'); + + } + break; + + default : + break loop47; + } + } while (true); + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return expr; + } + // $ANTLR end "bitwiseOr" + + + + // $ANTLR start "and" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1228:1: and returns [ExprTree expr] : op1= bitwiseOr ( '&&' op2= bitwiseOr )* ; + public final ExprTree and() throws RecognitionException { + ExprTree expr = null; + + + ExprTree op1 =null; + + ExprTree op2 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1229:5: (op1= bitwiseOr ( '&&' op2= bitwiseOr )* ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1229:9: op1= bitwiseOr ( '&&' op2= bitwiseOr )* + { + pushFollow(FOLLOW_bitwiseOr_in_and2433); + op1=bitwiseOr(); + + state._fsp--; + + + expr = op1; + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1230:6: ( '&&' op2= bitwiseOr )* + loop48: + do { + int alt48=2; + int LA48_0 = input.LA(1); + + if ( (LA48_0==AND) ) { + alt48=1; + } + + + switch (alt48) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1230:8: '&&' op2= bitwiseOr + { + match(input,AND,FOLLOW_AND_in_and2444); + + pushFollow(FOLLOW_bitwiseOr_in_and2448); + op2=bitwiseOr(); + + state._fsp--; + + + expr = new ExprTree(expr, op2, "&&", 'l'); + + } + break; + + default : + break loop48; + } + } while (true); + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return expr; + } + // $ANTLR end "and" + + + + // $ANTLR start "or" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1235:1: or returns [ExprTree expr] : op1= and ( '||' op2= and )* ; + public final ExprTree or() throws RecognitionException { + ExprTree expr = null; + + + ExprTree op1 =null; + + ExprTree op2 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1236:5: (op1= and ( '||' op2= and )* ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1236:9: op1= and ( '||' op2= and )* + { + pushFollow(FOLLOW_and_in_or2493); + op1=and(); + + state._fsp--; + + + expr = op1; + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1237:6: ( '||' op2= and )* + loop49: + do { + int alt49=2; + int LA49_0 = input.LA(1); + + if ( (LA49_0==OR) ) { + alt49=1; + } + + + switch (alt49) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1237:8: '||' op2= and + { + match(input,OR,FOLLOW_OR_in_or2504); + + pushFollow(FOLLOW_and_in_or2508); + op2=and(); + + state._fsp--; + + + expr = new ExprTree(expr, op2, "||", 'l'); + + } + break; + + default : + break loop49; + } + } while (true); + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return expr; + } + // $ANTLR end "or" + + + public static class implication_return extends ParserRuleReturnScope { + public ExprTree expr; + }; + + + // $ANTLR start "implication" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1242:1: implication returns [ExprTree expr] : op1= or ( '->' op2= or )* ; + public final PlatuGrammarParser.implication_return implication() throws RecognitionException { + PlatuGrammarParser.implication_return retval = new PlatuGrammarParser.implication_return(); + retval.start = input.LT(1); + + + ExprTree op1 =null; + + ExprTree op2 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1243:5: (op1= or ( '->' op2= or )* ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1243:7: op1= or ( '->' op2= or )* + { + pushFollow(FOLLOW_or_in_implication2548); + op1=or(); + + state._fsp--; + + + retval.expr = op1; + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1244:6: ( '->' op2= or )* + loop50: + do { + int alt50=2; + int LA50_0 = input.LA(1); + + if ( (LA50_0==IMPLICATION) ) { + alt50=1; + } + + + switch (alt50) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1244:8: '->' op2= or + { + match(input,IMPLICATION,FOLLOW_IMPLICATION_in_implication2559); + + pushFollow(FOLLOW_or_in_implication2563); + op2=or(); + + state._fsp--; + + + retval.expr = new ExprTree(retval.expr, op2, "->", 'l'); + + } + break; + + default : + break loop50; + } + } while (true); + + + } + + retval.stop = input.LT(-1); + + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return retval; + } + // $ANTLR end "implication" + + + + // $ANTLR start "expression" + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1248:1: expression returns [ExprTree expr] : op1= implication ( '?' op2= expression ':' op3= expression )? ; + public final ExprTree expression() throws RecognitionException { + ExprTree expr = null; + + + PlatuGrammarParser.implication_return op1 =null; + + ExprTree op2 =null; + + ExprTree op3 =null; + + + try { + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1249:5: (op1= implication ( '?' op2= expression ':' op3= expression )? ) + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1249:9: op1= implication ( '?' op2= expression ':' op3= expression )? + { + pushFollow(FOLLOW_implication_in_expression2604); + op1=implication(); + + state._fsp--; + + + expr = (op1!=null?op1.expr:null); + + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1250:6: ( '?' op2= expression ':' op3= expression )? + int alt51=2; + int LA51_0 = input.LA(1); + + if ( (LA51_0==QMARK) ) { + alt51=1; + } + switch (alt51) { + case 1 : + // /Users/zhangz/myBioSim/BioSim/gui/src/verification/platu/lpn/io/PlatuGrammar.g:1250:7: '?' op2= expression ':' op3= expression + { + match(input,QMARK,FOLLOW_QMARK_in_expression2614); + + pushFollow(FOLLOW_expression_in_expression2618); + op2=expression(); + + state._fsp--; + + + match(input,COLON,FOLLOW_COLON_in_expression2620); + + pushFollow(FOLLOW_expression_in_expression2624); + op3=expression(); + + state._fsp--; + + + + //expr = new TernaryNode(expr, op2, op3); + // op1?op2:op3 == int(op1)*op2+int(~op1)*op3 + //expr = new ExprTree(expr); + expr = new ExprTree(new ExprTree(new ExprTree("int("+(op1!=null?input.toString(op1.start,op1.stop):null) + ")"), op2, "*", 'a'), + new ExprTree(new ExprTree("int(~("+(op1!=null?input.toString(op1.start,op1.stop):null) + "))"), op3, "*", 'a'), + "+", 'a'); + + + } + break; + + } + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + + finally { + // do for sure before leaving + } + return expr; + } + // $ANTLR end "expression" + + // Delegated rules + + + protected DFA1 dfa1 = new DFA1(this); + static final String DFA1_eotS = + "\36\uffff"; + static final String DFA1_eofS = + "\36\uffff"; + static final String DFA1_minS = + "\1\34\1\32\2\23\1\uffff\2\25\1\20\1\17\1\20\1\17\1\31\1\74\1\25"+ + "\1\32\1\61\1\23\2\61\1\23\1\25\1\34\1\25\1\34\1\32\1\43\4\uffff"; + static final String DFA1_maxS = + "\1\34\1\74\2\23\1\uffff\2\34\1\20\1\17\1\20\1\17\1\31\1\74\1\31"+ + "\1\32\1\61\1\23\2\61\1\23\4\34\1\43\1\74\4\uffff"; + static final String DFA1_acceptS = + "\4\uffff\1\5\25\uffff\1\1\1\4\1\2\1\3"; + static final String DFA1_specialS = + "\36\uffff}>"; + static final String[] DFA1_transitionS = { + "\1\1", + "\1\3\10\uffff\1\4\30\uffff\1\2", + "\1\5", + "\1\6", + "", + "\1\7\6\uffff\1\10", + "\1\11\6\uffff\1\12", + "\1\13", + "\1\14", + "\1\15", + "\1\16", + "\1\17", + "\1\20", + "\1\22\3\uffff\1\21", + "\1\23", + "\1\24", + "\1\25", + "\1\26", + "\1\26", + "\1\27", + "\1\7\6\uffff\1\10", + "\1\30", + "\1\11\6\uffff\1\12", + "\1\31", + "\1\32\10\uffff\1\33", + "\1\35\30\uffff\1\34", + "", + "", + "", + "" + }; + + static final short[] DFA1_eot = DFA.unpackEncodedString(DFA1_eotS); + static final short[] DFA1_eof = DFA.unpackEncodedString(DFA1_eofS); + static final char[] DFA1_min = DFA.unpackEncodedStringToUnsignedChars(DFA1_minS); + static final char[] DFA1_max = DFA.unpackEncodedStringToUnsignedChars(DFA1_maxS); + static final short[] DFA1_accept = DFA.unpackEncodedString(DFA1_acceptS); + static final short[] DFA1_special = DFA.unpackEncodedString(DFA1_specialS); + static final short[][] DFA1_transition; + + static { + int numStates = DFA1_transitionS.length; + DFA1_transition = new short[numStates][]; + for (int i=0; i LpnMap = new HashMap(); // all modules parsed, keyed by module name + static private HashMap GlobalVarHashMap = new HashMap(); // global variables and associated values + static private HashMap GlobalVarNodeMap = new HashMap(); + static public List InstanceList = new ArrayList(); + static public HashSet includeSet = new HashSet(); + + // non-static variables + private HashMap VarNodeMap = new HashMap(); // maps variable name to variable object + private DualHashMap VarIndexMap = new DualHashMap(); // maps variables to an array index + private HashMap GlobalConstHashMap = new HashMap(); // global constants within a single lpn file + private HashMap ConstHashMap = new HashMap(); // constants within a single module + private HashMap StatevectorMap = new HashMap(); // module variables mapped to initial values + private HashMap VarCountMap = new HashMap(); // count of the references to each module variable + private List inputTranList = null; // list of lpn transitions which affect a modules input + private List outputTranList = null; // list of lpn transitions which affect a modules output + private List argumentList = null; // list of class arguments + private VarSet Inputs = null; // module inputs + private VarSet Internals = null; // module internal variables + private VarSet Outputs = null; // module outputs + private int VariableIndex = 0; // count of index assigned to module variables + private int TransitionIndex = 0; // count of index assigned to lpn transitions + private int GlobalCount = 0; // number of global variables defined in this lpn file + private int GlobalSize = 0; // number of global variables defined + + // methods + private void error(String error){ + System.err.println(error); + System.exit(1); + } + + private void createGlobalArray(String var, List dimensionList){ + int iter = dimensionList.size() - 1; + int dIndex = 0; + int arraySize = dimensionList.get(dIndex++); + int lastSize = 0; + List topLevelArray = new ArrayList(arraySize); + + Queue> arrayQueue = new LinkedList>(); + arrayQueue.offer(topLevelArray); + + while(iter > 0){ + lastSize = arraySize; + arraySize = dimensionList.get(dIndex++); + int qSize = arrayQueue.size(); + for(int i = 0; i < qSize; i++){ + List array = arrayQueue.poll(); + for(int j = 0 ; j < lastSize; j++){ + List newArray = new ArrayList(arraySize); + array.add(j, newArray); + arrayQueue.offer(newArray); + } + } + + iter--; + } + + int varCount = 0; + dIndex--; + arraySize = dimensionList.get(dIndex); + + List varList = new ArrayList(); + while(!arrayQueue.isEmpty()){ + List array = arrayQueue.poll(); + for(int i = 0; i < arraySize; i++){ + String name = var + "." + varCount; + varCount++; + + int index = VariableIndex++; + VarNode element = new VarNode(name, index); + element.setType(platu.lpn.VarType.GLOBAL); + array.add(i, element); + varList.add(element); + + // add variable and value to state vector + StatevectorMap.put(name, 0); + + // generate variable index and create new var node + VarIndexMap.insert(name, index); + VarNodeMap.put(name, element); + } + } + + ArrayNode newArray = new ArrayNode(var, topLevelArray, dimensionList.size(), dimensionList, varList); + newArray.setType(platu.lpn.VarType.GLOBAL); + VarNodeMap.put(var, newArray); +// VarCountMap.put(var, 0); +// Inputs.add(var); + Outputs.add(var); + } + + private void createInputArray(String var, List dimensionList){ + int iter = dimensionList.size() - 1; + int dIndex = 0; + int arraySize = dimensionList.get(dIndex++); + int lastSize = 0; + List topLevelArray = new ArrayList(arraySize); + + Queue> arrayQueue = new LinkedList>(); + arrayQueue.offer(topLevelArray); + + while(iter > 0){ + lastSize = arraySize; + arraySize = dimensionList.get(dIndex++); + int qSize = arrayQueue.size(); + for(int i = 0; i < qSize; i++){ + List array = arrayQueue.poll(); + for(int j = 0 ; j < lastSize; j++){ + List newArray = new ArrayList(arraySize); + array.add(j, newArray); + arrayQueue.offer(newArray); + } + } + + iter--; + } + + int varCount = 0; + dIndex--; + arraySize = dimensionList.get(dIndex); + + List varList = new ArrayList(); + while(!arrayQueue.isEmpty()){ + List array = arrayQueue.poll(); + for(int i = 0; i < arraySize; i++){ + String name = var + "." + varCount; + varCount++; + + int index = VariableIndex++; + VarNode element = new VarNode(name, index); + element.setType(platu.lpn.VarType.INPUT); + array.add(i, element); + varList.add(element); + + // add variable and value to state vector + StatevectorMap.put(name, 0); + + // generate variable index and create new var node + VarIndexMap.insert(name, index); + VarNodeMap.put(name, element); + } + } + + ArrayNode newArray = new ArrayNode(var, topLevelArray, dimensionList.size(), dimensionList, varList); + newArray.setType(platu.lpn.VarType.INPUT); + VarNodeMap.put(var, newArray); +// VarCountMap.put(var, 0); + Inputs.add(var); + argumentList.add(var); + } +} + +@rulecatch{ + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } +} + +@lexer::header{ + package platu.lpn.io; +} + +parseLpnFile[Project prj] + : include? globalConstants? globalVariables? //((globalConstants globalVariables) | (globalVariables globalConstants) | (globalVariables) | (globalConstants))? + { + // check that global constants are consistently defined in each lpn file + if(GlobalSize > 0 && GlobalCount != GlobalSize){ + System.err.println("error: global variable definitions are inconsistent"); + System.exit(1); + } + } + main[prj]? (moduleClass[prj])* EOF + ; + +include + : '<' 'include' '>' (PATH ';' + { + File f = new File($PATH.text); + includeSet.add(f.getAbsolutePath()); + } + )+ '<' '/include' '>' + ; + +main[Project prj] + : '<' 'mod' 'name' '=' '"' 'main' '"' '>' + { + if(main == true){ + System.err.println("error: multiple main modules"); + System.exit(1); + } + + main = true; + + // initialize non static variables for new module + VarIndexMap = new DualHashMap(); + ConstHashMap = new HashMap(); + VarNodeMap = new HashMap(); + VarCountMap = new HashMap(); + Inputs = new VarSet(); + Internals = new VarSet(); + Outputs = new VarSet(); + inputTranList = new LinkedList(); + outputTranList = new LinkedList(); + argumentList = new ArrayList(); + StatevectorMap = new HashMap(); + VariableIndex = 0; + + // add global variables to initial state vector and label as an input & output + for(Entry e : GlobalVarHashMap.entrySet()){ + String globalVar = e.getKey(); + if(GlobalVarNodeMap.containsKey(globalVar)) continue; + + StatevectorMap.put(globalVar, e.getValue()); + int index = VariableIndex++; + VarIndexMap.insert(globalVar, index); + + VarNode globalVarNode = new VarNode(globalVar, index); + globalVarNode.setType(platu.lpn.VarType.GLOBAL); + VarNodeMap.put(globalVar, globalVarNode); +// Inputs.add(globalVar); + Outputs.add(globalVar); + } + + // add global arrays + for(VarNode node : GlobalVarNodeMap.values()){ + ArrayNode arrayNode = (ArrayNode) node; + + // construct array + createGlobalArray(arrayNode.getName(), arrayNode.getDimensionList()); + } + } + variables? constants? instantiation '<' '/mod' '>' + ; + +process + : '<' 'process' 'name' '=' '"' processName=ID '"' '>' '<' '/process' '>' + ; + +// TODO: don't enforce order +moduleClass[Project prj] returns [LPN lpn] + : ( '<' 'class' 'name' '=' '"' modName=ID + { + // module names must be unique + if(LpnMap.containsKey($modName.text)){ + System.err.println("error on line " + $modName.getLine() + ": module " + $modName.text + " already exists"); + System.exit(1); + } + + if($modName.text.equals("main")){ + error("error on line " + $modName.getLine() + ": main is reserved"); + } + + // initialize non static variables for new module + VarIndexMap = new DualHashMap(); + ConstHashMap = new HashMap(); + VarNodeMap = new HashMap(); + VarCountMap = new HashMap(); + Inputs = new VarSet(); + Internals = new VarSet(); + Outputs = new VarSet(); + inputTranList = new LinkedList(); + outputTranList = new LinkedList(); + argumentList = new ArrayList(); + StatevectorMap = new HashMap(); + VariableIndex = 0; + + // add global variables to initial state vector and label as an input & output + for(Entry e : GlobalVarHashMap.entrySet()){ + String globalVar = e.getKey(); + if(GlobalVarNodeMap.containsKey(globalVar)) continue; + + StatevectorMap.put(globalVar, e.getValue()); + int index = VariableIndex++; + VarIndexMap.insert(globalVar, index); + + VarNode globalVarNode = new VarNode(globalVar, index); + globalVarNode.setType(platu.lpn.VarType.GLOBAL); + VarNodeMap.put(globalVar, globalVarNode); +// Inputs.add(globalVar); + Outputs.add(globalVar); + } + + // add global arrays + for(VarNode node : GlobalVarNodeMap.values()){ + ArrayNode arrayNode = (ArrayNode) node; + + // construct array + createGlobalArray(arrayNode.getName(), arrayNode.getDimensionList()); + } + } + '"' 'arg' '=' '"' (((arrayArg2=ID + { + // check aginst globals and other inputs + if(GlobalConstHashMap.containsKey($arrayArg2.text)){ + System.err.println("error on line " + $arrayArg2.getLine() + ": variable " + $arrayArg2.text + " is already defined as a global constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey($arrayArg2.text)){ + System.err.println("error on line " + $arrayArg2.getLine() + ": variable " + $arrayArg2.text + " is already defined as a global variable"); + System.exit(1); + } + else if(VarNodeMap.containsKey($arrayArg2.text)){ + System.err.println("error on line " + $arrayArg2.getLine() + ": variable " + $arrayArg2.text + " is already defined"); + System.exit(1); + } + + List dimensionList = new ArrayList(); + } + ('[' arrayExpr2=expression + { + dimensionList.add($arrayExpr2.value); + } + ']')+ + { + createInputArray($arrayArg2.text, dimensionList); + } + ) | (arg2=ID + { + // check against globals + if(GlobalConstHashMap.containsKey($arg2.text)){ + System.err.println("error on line " + $arg2.getLine() + ": variable " + $arg2.text + " is already defined as a global constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey($arg2.text)){ + System.err.println("error on line " + $arg2.getLine() + ": variable " + $arg2.text + " is already defined as a global variable"); + System.exit(1); + } + + // add variable and value to state vector + StatevectorMap.put($arg2.getText(), 0); + + // generate variable index and create new var node + int index = VariableIndex++; + VarIndexMap.insert($arg2.getText(), index); + + VarNode inputVarNode = new VarNode($arg2.getText(), index); + inputVarNode.setType(platu.lpn.VarType.INPUT); + VarNodeMap.put($arg2.getText(), inputVarNode); +// VarCountMap.put($arg2.getText(), 0); + + argumentList.add($arg2.getText()); + Inputs.add($arg2.getText()); + } + )) ((',' arrayArg=ID + { + // check aginst globals and other inputs + if(GlobalConstHashMap.containsKey($arrayArg.text)){ + System.err.println("error on line " + $arrayArg.getLine() + ": variable " + $arrayArg.text + " is already defined as a global constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey($arrayArg.text)){ + System.err.println("error on line " + $arrayArg.getLine() + ": variable " + $arrayArg.text + " is already defined as a global variable"); + System.exit(1); + } + else if(VarNodeMap.containsKey($arrayArg.text)){ + System.err.println("error on line " + $arrayArg.getLine() + ": variable " + $arrayArg.text + " is already defined"); + System.exit(1); + } + + List dimensionList = new ArrayList(); + } + ('[' arrayExpr=expression + { + dimensionList.add($arrayExpr.value); + } + ']')+ + { + createInputArray($arrayArg.text, dimensionList); + } + ) | (',' arg=ID + { + // check aginst globals and other inputs + if(GlobalConstHashMap.containsKey($arg.text)){ + System.err.println("error on line " + $arg.getLine() + ": variable " + $arg.text + " is already defined as a global constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey($arg.text)){ + System.err.println("error on line " + $arg.getLine() + ": variable " + $arg.text + " is already defined as a global variable"); + System.exit(1); + } + else if(VarNodeMap.containsKey($arg.text)){ + System.err.println("error on line " + $arg.getLine() + ": variable " + $arg.text + " is already defined"); + System.exit(1); + } + + // add variable and value to state vector + StatevectorMap.put($arg.getText(), 0); + + // generate variable index and create new var node + int index = VariableIndex++; + VarIndexMap.insert($arg.getText(), index); + + VarNode inputVarNode = new VarNode($arg.getText(), index); + inputVarNode.setType(platu.lpn.VarType.INPUT); + VarNodeMap.put($arg.getText(), inputVarNode); +// VarCountMap.put($arg.getText(), 0); + + argumentList.add($arg.getText()); + Inputs.add($arg.getText()); + } + ))* )? '"' '>' constants? variables logic '<' '/class' '>' + { + for(Entry e : VarCountMap.entrySet()){ + if(e.getValue() == 0){ + System.out.println("warning: variable '" + e.getKey() + "' is never assigned"); + } + } + + // create new lpn +// Zone zone; +// if (Main.ZONE_VERSION == 2) { +// zone = new HashedHashedMapZoneImpl(); +// } +// else if (Main.ZONE_VERSION == 3) { +// zone = new HashedHashedMapZoneImpl(); +// } +// else { +// zone = new HashedHashedMapZoneImpl(); +// } + + int[] initialMarking = new int[$logic.initMarking.size()]; + + int i = 0; + for(Integer mark : $logic.initMarking){ + initialMarking[i++] = mark; + } + + $lpn = new LPN(prj, $modName.text, Inputs, Outputs, Internals, VarNodeMap, $logic.lpnTranSet, + StatevectorMap, initialMarking); + + $lpn.addAllInputTrans(inputTranList); + $lpn.addAllOutputTrans(outputTranList); + $lpn.setVarIndexMap(VarIndexMap); + $logic.lpnTranSet.setLPN($lpn); + + LpnMap.put($lpn.getLabel(), $lpn); + $lpn.setArgumentList(argumentList); + } + ) + ; + +constants + : '<' 'const' '>' (const1=ID '=' val1=INT + { + // make sure constant is not defined as something else + if(VarNodeMap.containsKey($const1.text)){ + System.err.println("error on line " + $const1.getLine() + ": " + $const1.text + " already exists as a variable"); + System.exit(1); + } + else if(GlobalConstHashMap.containsKey($const1.text)){ + System.err.println("error on line " + $const1.getLine() + ": " + $const1.text + " already exists as a global constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey($const1.text)){ + System.err.println("error on line " + $const1.getLine() + ": " + $const1.text + " is already defined as a global variable"); + System.exit(1); + } + + // put will override previous value + Integer result = ConstHashMap.put($const1.text, Integer.parseInt($val1.text)); + if(result != null){ + System.err.println("error on line " + $const1.getLine() + ": " + $const1.text + " has already been defined"); + System.exit(1); + } + } + ';')* '<' '/const' '>' + ; + +globalConstants + : '<' 'const' '>' (const1=ID '=' val1=INT + { + // make sure constant has not been defined already + if(GlobalVarHashMap.containsKey($const1.text)){ + System.err.println("error on line " + $const1.getLine() + ": " + $const1.text + " is already defined as a global variable"); + System.exit(1); + } + + // put will override previous value + Integer result = GlobalConstHashMap.put($const1.text, Integer.parseInt($val1.text)); + if(result != null){ + System.err.println("error on line " + $const1.getLine() + ": " + $const1.text + " has already been defined"); + System.exit(1); + } + } + ';')* '<' '/const' '>' + ; + +globalVariables + : '<' 'var' '>' (globalVarDecl | globalArrayDecl)+ '<' '/var' '>' + ; + +globalVarDecl + : var=ID + { + // make sure global variables are consistently defined in each lpn file + if(GlobalSize == 0){ + if(GlobalConstHashMap.containsKey($var.text)){ + System.err.println("error on line" + $var.getLine() + ": " + $var.text + "already exists as a constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey($var.text)){ + System.err.println("error on line " + $var.getLine() + ": " + $var.text + " has already been defined"); + System.exit(1); + } + } + else{ + if(!GlobalVarHashMap.containsKey($var.text)){ + System.err.println("error on line " + $var.getLine() + ": " + $var.text + " is inconsistently defined"); + System.exit(1); + } + } + + GlobalCount++; + } + '=' (val=INT + { + // make sure global variables are consistently initialized + int value = Integer.parseInt($val.text); + if(GlobalSize == 0){ + GlobalVarHashMap.put($var.text, value); + } + else{ + int globalVal = GlobalVarHashMap.get($var.text); + if(globalVal != value){ + System.err.println("error on line " + $val.getLine() + ": " + $var.text + " is inconsistently assigned"); + System.exit(1); + } + } + } + | var2=ID + { + // get value of variable + Integer value = null; + if(GlobalConstHashMap.containsKey($var2.text)){ + value = GlobalConstHashMap.get($var2.text); + } + else if(GlobalVarHashMap.containsKey($var2.text)){ + System.err.println("error on line " + $var2.getLine() + ": global variable " + $var2.text + " cannot be assigned to global variable " + $var.text); + System.exit(1); + } + else{ + System.err.println("error on line " + $var2.getLine() + ": " + $var2.text + " is not defined"); + System.exit(1); + } + + // make sure global variable is consitently initialized + if(GlobalSize == 0){ + GlobalVarHashMap.put($var.text, value); + } + else{ + int globalVal = GlobalVarHashMap.get($var.text); + if(globalVal != value){ + System.err.println("error on line " + $var2.getLine() + ": " + $var.text + " is inconsistently assigned"); + System.exit(1); + } + } + } + ) ';' + ; + +globalArrayDecl + : arrayVar=ID + { + List dimensionList = new ArrayList(); + + // make sure global variables are consistently defined in each lpn file + if(GlobalSize == 0){ + if(GlobalConstHashMap.containsKey($arrayVar.text)){ + System.err.println("error on line" + $arrayVar.getLine() + ": " + $arrayVar.text + "already exists as a constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey($arrayVar.text)){ + System.err.println("error on line " + $arrayVar.getLine() + ": " + $arrayVar.text + " has already been defined"); + System.exit(1); + } + } + else{ + if(!GlobalVarHashMap.containsKey($arrayVar.text)){ + System.err.println("error on line " + $arrayVar.getLine() + ": " + $arrayVar.text + " is inconsistently defined"); + System.exit(1); + } + } + + GlobalCount++; + } + ('[' (arrayExpr=expression + { + dimensionList.add($arrayExpr.value); + } + ) ']')+ ';' + { + // make sure global variables are consistently initialized + if(GlobalSize == 0){ + GlobalVarHashMap.put($arrayVar.text, 0); + GlobalVarNodeMap.put($arrayVar.text, new ArrayNode($arrayVar.text, null, dimensionList.size(), dimensionList, null)); + } + else{ + ArrayNode node = (ArrayNode) GlobalVarNodeMap.get($arrayVar.text); + if(node.getDimensions() != dimensionList.size()){ + error("error on line " + $arrayVar.getLine() + ": " + $arrayVar.text + " is inconsistently assigned"); + } + + List dimList = node.getDimensionList(); + for(int i = 0; i < dimensionList.size(); i++){ + if(dimList.get(i) != dimensionList.get(i)){ + error("error on line " + $arrayVar.getLine() + ": " + $arrayVar.text + " is inconsistently assigned"); + } + } + } + } + ; +variables + : '<' 'var' '>' ( varDecl | arrayDecl)+ '<' '/var' '>' + ; + +varDecl + : {Integer value = null; Token varNode = null;} + var=ID + { + // check variable is unique in scope + if(GlobalConstHashMap.containsKey($var.text)){ + System.err.println("error on line " + $var.getLine() + ": " + $var.text + " is a global constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey($var.text)){ + System.err.println("error on line " + $var.getLine() + ": " + $var.text + " is a global variable"); + System.exit(1); + } + else if(VarNodeMap.containsKey($var.text)){ + System.err.println("error on line " + $var.getLine() + ": " + $var.text + " has already been defined"); + System.exit(1); + } + + varNode = var; + } + '=' (val=INT + { + // get variable initial value + value = Integer.parseInt($val.text); + } + | var2=ID + { + // get variable initial value + if(GlobalConstHashMap.containsKey($var2.text)){ + value = GlobalConstHashMap.get($var2.text); + } + else if(GlobalVarHashMap.containsKey($var2.text)){ + value = GlobalVarHashMap.get($var2.text); + } + else if(ConstHashMap.containsKey($var2.text)){ + value = ConstHashMap.get($var2.text); + } + else if(StatevectorMap.containsKey($var2.text)){ // Should var be allowed to assign a var? + value = StatevectorMap.get($var.text); + } + else{ + System.err.println("error on line " + $var2.getLine() + ": " + $var2.text + " is not defined or is not compatible"); + System.exit(1); + } + + varNode = var2; + } + ) + { + // add variable and value to state vector + StatevectorMap.put(varNode.getText(), value); + + // generate variable index and create new var node + int index = VariableIndex++; + VarIndexMap.insert(varNode.getText(), index); + + VarNode internalVar = new VarNode(varNode.getText(), index); + internalVar.setType(platu.lpn.VarType.INTERNAL); + VarNodeMap.put(varNode.getText(), internalVar); + VarCountMap.put(varNode.getText(), 0); + + Internals.add(varNode.getText()); + } + ';' + ; + +arrayDecl + : var=ID + { + List dimensionList = new ArrayList(); + } + ('[' (arrayExpr=expression + { + dimensionList.add($arrayExpr.value); + } + ) ']')+ + { + int iter = dimensionList.size() - 1; + int dIndex = 0; + int arraySize = dimensionList.get(dIndex++); + int lastSize = 0; + List topLevelArray = new ArrayList(arraySize); + + Queue> arrayQueue = new LinkedList>(); + arrayQueue.offer(topLevelArray); + + while(iter > 0){ + lastSize = arraySize; + arraySize = dimensionList.get(dIndex++); + int qSize = arrayQueue.size(); + for(int i = 0; i < qSize; i++){ + List array = arrayQueue.poll(); + for(int j = 0 ; j < lastSize; j++){ + List newArray = new ArrayList(arraySize); + array.add(j, newArray); + arrayQueue.offer(newArray); + } + } + + iter--; + } + + int varCount = 0; + dIndex--; + arraySize = dimensionList.get(dIndex); + + List varList = new ArrayList(); + while(!arrayQueue.isEmpty()){ + List array = arrayQueue.poll(); + for(int i = 0; i < arraySize; i++){ + String name = $var.text + "." + varCount; + varCount++; + + int index = VariableIndex++; + VarNode element = new VarNode(name, index); + element.setType(platu.lpn.VarType.INTERNAL); + array.add(i, element); + varList.add(element); + + // add variable and value to state vector + StatevectorMap.put(name, 0); + + // generate variable index and create new var node + VarIndexMap.insert(name, index); + VarNodeMap.put(name, element); + } + } + + ArrayNode newArray = new ArrayNode($var.text, topLevelArray, dimensionList.size(), dimensionList, varList); + newArray.setType(platu.lpn.VarType.INTERNAL); + VarNodeMap.put($var.text, newArray); + VarCountMap.put($var.text, 0); + Internals.add($var.text); + } + ('=' + { + List valueList = new ArrayList(); + } + '{' (val2=INT + { + Integer dimVal = Integer.parseInt($val2.text); + if(dimVal < 1){ + error("error on line " + $val2.getLine() + ": invalid dimension"); + } + + valueList.add(dimVal); + } + | var2=ID + { + Integer initVal = null; + + // get variable initial value + if(GlobalConstHashMap.containsKey($var2.text)){ + initVal = GlobalConstHashMap.get($var2.text); + } + else if(GlobalVarHashMap.containsKey($var2.text)){ + initVal = GlobalVarHashMap.get($var2.text); + } + else if(ConstHashMap.containsKey($var2.text)){ + initVal = ConstHashMap.get($var2.text); + } + else if(StatevectorMap.containsKey($var2.text)){ // Should var be allowed to assign a var? + initVal = StatevectorMap.get($var2.text); + } + else{ + System.err.println("error on line " + $var2.getLine() + ": " + $var2.text + " is not defined"); + System.exit(1); + } + + if(initVal < 1){ + error("error on line " + $var2.getLine() + ": invalid dimension"); + } + + valueList.add(initVal); + } + )+ '}' + { + //TODO: initialize array + int dimensions = dimensionList.size(); + } + )? ';' + ; + +instantiation + : (modName=ID instName=ID + { + List argList = new ArrayList(); + List modList = new ArrayList(); + } + '('((var=MEMBER ',' + { + String buffer = $var.text; + StringTokenizer tk = new StringTokenizer(buffer, "."); + + String module = tk.nextToken(); + String variable = tk.nextToken(); + + modList.add(module); + argList.add(module + "." + variable); + } + )* var2=MEMBER + { + String buffer = $var2.text; + StringTokenizer tk = new StringTokenizer(buffer, "."); + + String module = tk.nextToken(); + String variable = tk.nextToken(); + + modList.add(module); + argList.add(module + "." + variable); + } + )?')' ';' + { + Instance inst = new Instance($modName.text, $instName.text, argList, modList); + InstanceList.add(inst); + } + )+ + ; + +logic returns [List initMarking, LpnTranList lpnTranSet] + : {$lpnTranSet = new LpnTranList();} + marking (transition {$lpnTranSet.add($transition.lpnTran);})+ + { + $initMarking = $marking.mark; + } + ; + +marking returns [List mark] + : {$mark = new LinkedList(); Integer result;} + ('<' 'marking' '>' ((m1=INT + { + $mark.add(Integer.parseInt($m1.text)); + } + | c1=ID + { + result = ConstHashMap.get($c1.text); + if(result == null){ + System.err.println("error on line " + $c1.getLine() + ": " + $c1.text + " is not a valid constant"); + System.exit(1); + } + + $mark.add(result); + } + ) (',' (m2=INT + { + $mark.add(Integer.parseInt($m2.text)); + } + | c2=ID + { + result = ConstHashMap.get($c2.text); + if(result == null){ + System.err.println("error on line " + $c2.getLine() + ": " + $c2.text + " is not a valid constant"); + System.exit(1); + } + + $mark.add(result); + } + ))*)? '<' '/marking' '>')? + ; + +transition returns [LPNTran lpnTran] + : { + Integer result = null; + ArrayList presetList = new ArrayList(); + ArrayList postsetList = new ArrayList(); + VarExprList assignmentList = new VarExprList(); + ArrayList assertionList = new ArrayList(); + Expression guardExpr = TrueExpr; + int delayLB = 0; + int delayUB = INFINITY; + boolean local = true; + } + '<' 'transition' 'label' '=' '"' lbl=(ID|INT) '"' 'preset' '=' ('"' '"' | ('"' (pre=INT + { + presetList.add(Integer.parseInt($pre.text)); + } + | pre1=ID + { + result = ConstHashMap.get($pre1.text); + if(result == null){ + System.err.println("error on line " + $pre1.getLine() + ": " + $pre1.text + " is not a constant"); + System.exit(1); + } + + presetList.add(result); + } + ) ( ',' pre2=INT + { + presetList.add(Integer.parseInt($pre2.text)); + } + | ',' pre3=ID + { + result = ConstHashMap.get($pre3.text); + if(result == null){ + System.err.println("error on line " + $pre3.getLine() + ": " + $pre3.text + " is not a constant"); + System.exit(1); + } + + presetList.add(result); + } + )* '"')) 'postset' '=' ( '"' '"' | ('"' ( post=INT + { + postsetList.add(Integer.parseInt($post.text)); + } + | post1=ID + { + result = ConstHashMap.get($post1.text); + if(result == null){ + System.err.println("error on line " + $post1.getLine() + ": " + $post1.text + " is not a constant"); + System.exit(1); + } + + postsetList.add(result); + } + ) + ( (',' post2=INT + { + postsetList.add(Integer.parseInt($post2.text)); + } + ) | (','post3=ID + { + result = ConstHashMap.get($post3.text); + if(result == null){ + System.err.println("error on line " + $post3.getLine() + ": " + $post3.text + " is not a constant"); + System.exit(1); + } + + postsetList.add(result); + } + ))* '"' )) '>' (guard + { + guardExpr = $guard.expr; + } + )? (delay + { + delayLB = $delay.delayLB; + delayUB = $delay.delayUB; + } + )? ((assertion + { + if($assertion.booleanExpr != null){ + assertionList.add($assertion.booleanExpr); + } + } + ) | (assignment + { + assignmentList.add($assignment.assign); + } + ))* '<' '/transition' '>' + { + // create new lpn transitions and add assertions + $lpnTran = new LPNTran($lbl.text, TransitionIndex++, presetList, postsetList, guardExpr, assignmentList, delayLB, delayUB, local); + if(assertionList.size() > 0){ + $lpnTran.addAllAssertions(assertionList); + } + } + ; + +assertion returns [Expression booleanExpr] + : {booleanExpr = null;} + 'assert' '(' expression ')' ';' + { + $booleanExpr = new Expression($expression.expr); + } + ; + +guard returns [Expression expr] + : 'condition' '(' expression ')' ';' + { + $expr = new Expression($expression.expr); + } + ; + +delay returns [int delayLB, int delayUB] + : 'delay' '(' lb=INT + { + $delayLB = Integer.parseInt($lb.text); + } + ',' (ub=INT + { + $delayUB = Integer.parseInt($ub.text); + // make sure delays are >= 0 and upper bound is >= lower bound + if($delayLB < 0){ + System.err.println("error on line " + $lb.getLine() + ": lower bound " + $delayLB + " must be >= 0"); + System.exit(1); + } + else if($delayLB == INFINITY){ + System.err.println("error on line " + $ub.getLine() + ": lower bound " + $delayUB + " must be a non-negative finite number"); + System.exit(1); + } + else if($delayUB < $delayLB){ + System.err.println("error on line " + $ub.getLine() + ": upper bound " + $delayUB + " < lower bound " + $delayLB); + System.exit(1); + } + } + | 'inf' + { + $delayUB = INFINITY; + } + ) ')' ';' + ; + +assignment returns [VarExpr assign] + : (var1=ID '=' var2=ID) + { + // make sure only global, internal and output variables are assigned + if(GlobalConstHashMap.containsKey($var1.text)){ + System.err.println("error on line " + $var1.getLine() + ": global constant " + $var1.text + " cannot be assigned"); + System.exit(1); + } + else if(ConstHashMap.containsKey($var1.text)){ + System.err.println("error on line " + $var1.getLine() + ": constant " + $var1.text + " cannot be assigned"); + System.exit(1); + } + else if(!VarNodeMap.containsKey($var1.text)){ + System.err.println("error on line " + $var1.getLine() + ": variable " + $var1.text + " was not declared"); + System.exit(1); + } + else if(!Outputs.contains($var1.text) && !Internals.contains($var.text)){ + System.err.println("error on line " + $var1.getLine() + ": input variable " + $var1.text + " cannot be assigned"); + System.exit(1); + } + + ExpressionNode node2 = null; + if(GlobalConstHashMap.containsKey($var2.text)){ + node2 = new ConstNode($var2.text, GlobalConstHashMap.get($var2.text)); + } + else if(ConstHashMap.containsKey($var2.text)){ + node2 = new ConstNode($var2.text, ConstHashMap.get($var2.text)); + } + else if(GlobalVarHashMap.containsKey($var2.text)){ + node2 = VarNodeMap.get($var2.text); + } + else if(!VarNodeMap.containsKey($var2.text)){ + System.err.println("error on line " + $var2.getLine() + ": variable " + $var2.text + " was not declared"); + System.exit(1); + } + else{ + node2 = VarNodeMap.get($var2.text); + } + + VarNode node1 = VarNodeMap.get($var1.text); + if(ArrayNode.class.isAssignableFrom(node1.getClass())){ + if(!ArrayNode.class.isAssignableFrom(node2.getClass())){ + System.err.println("error on line " + $var.getLine() + ": variable " + $var.text + " is an array"); + System.exit(1); + } + + ArrayNode arrayNode1 = (ArrayNode) node1; + ArrayNode arrayNode2 = (ArrayNode) node2; + + List dimensionList1 = arrayNode1.getDimensionList(); + List dimensionList2 = arrayNode2.getDimensionList(); + + if(dimensionList1.size() != dimensionList2.size()){ + System.err.println("error on line " + $var1.getLine() + ": incompatible array dimensions"); + System.exit(1); + } + + for(int i = 0; i < dimensionList1.size(); i++){ + if(dimensionList1.get(i) != dimensionList2.get(i)){ + System.err.println("error on line " + $var1.getLine() + ": incompatible array dimensions"); + System.exit(1); + } + } + + //TODO: array to array assignment + + }else if(ArrayNode.class.isAssignableFrom(node2.getClass())){ + System.err.println("error on line " + $var2.getLine() + ": variable " + $var2.text + " is an array"); + System.exit(1); + } + else{ + // regular assignment + Expression expr = new Expression(node2); + $assign = new VarExpr(node1, expr); + } + + if(node1.getType() == platu.lpn.VarType.INTERNAL || node1.getType() == platu.lpn.VarType.OUTPUT){ + Integer varCount = VarCountMap.get($var1.text); + VarCountMap.put($var1.text, ++varCount); + } + } + | (var=ID '=' + { + // make sure only global, internal and output variables are assigned + if(GlobalConstHashMap.containsKey($var.text)){ + System.err.println("error on line " + $var.getLine() + ": global constant " + $var.text + " cannot be assigned"); + System.exit(1); + } + else if(ConstHashMap.containsKey($var.text)){ + System.err.println("error on line " + $var.getLine() + ": constant " + $var.text + " cannot be assigned"); + System.exit(1); + } + else if(!VarNodeMap.containsKey($var.text)){ + System.err.println("error on line " + $var.getLine() + ": variable " + $var.text + " was not declared"); + System.exit(1); + } + else if(!Outputs.contains($var.text) && !Internals.contains($var.text)){ + System.err.println("error on line " + $var.getLine() + ": input variable " + $var.text + " cannot be assigned"); + System.exit(1); + } + } + varExpr=expression + { + Expression expr = new Expression($varExpr.expr); + VarNode node = VarNodeMap.get($var.text); + if(ArrayNode.class.isAssignableFrom(node.getClass())){ + System.err.println("error on line " + $var.getLine() + ": variable " + $var.text + " is an array"); + System.exit(1); + } + + if(node.getType() == platu.lpn.VarType.INTERNAL || node.getType() == platu.lpn.VarType.OUTPUT){ + Integer varCount = VarCountMap.get($var.text); + VarCountMap.put($var.text, ++varCount); + } + + $assign = new VarExpr(node, expr); + } + ';') | (arrayVar=ID + { + List indexList = new ArrayList(); + + // make sure only global, internal and output variables are assigned + if(GlobalConstHashMap.containsKey($arrayVar.text)){ + System.err.println("error on line " + $arrayVar.getLine() + ": global constant " + $arrayVar.text + " cannot be assigned"); + System.exit(1); + } + else if(ConstHashMap.containsKey($arrayVar.text)){ + System.err.println("error on line " + $arrayVar.getLine() + ": constant " + $arrayVar.text + " cannot be assigned"); + System.exit(1); + } + else if(!VarNodeMap.containsKey($arrayVar.text)){ + System.err.println("error on line " + $arrayVar.getLine() + ": variable " + $arrayVar.text + " was not declared"); + System.exit(1); + } + else if(!Outputs.contains($arrayVar.text) && !Internals.contains($arrayVar.text)){ + System.err.println("error on line " + $arrayVar.getLine() + ": input variable " + $arrayVar.text + " cannot be assigned"); + System.exit(1); + } + } + ('[' (arrayExpr=expression + { + ExpressionNode node = $arrayExpr.expr; + indexList.add(node); + } + ) ']')+ '=' assignExpr=expression + { + Expression expr = new Expression($assignExpr.expr); + VarNode arrayNode = VarNodeMap.get($arrayVar.text); + if(ArrayNode.class.isAssignableFrom(arrayNode.getClass())){ + $assign = new VarExpr(new ArrayElement((ArrayNode) arrayNode, indexList), expr); + } + else{ + System.err.println("error on line " + $arrayVar.getLine() + ": " + $arrayVar.text + " is not an array"); + System.exit(1); + } + + if(arrayNode.getType() == platu.lpn.VarType.INTERNAL || arrayNode.getType() == platu.lpn.VarType.OUTPUT){ + Integer varCount = VarCountMap.get($arrayVar.text); + VarCountMap.put($arrayVar.text, ++varCount); + } + } + ';') + ; + +// Expressions +term returns [ExpressionNode expr, int value] + : var=ID + { + if(ConstHashMap.containsKey($var.text)){ + $value = ConstHashMap.get($var.text); + $expr = new ConstNode($var.text, $value); + } + else if(GlobalConstHashMap.containsKey($var.text)){ + $value = GlobalConstHashMap.get($var.text); + $expr = new ConstNode($var.text, $value); + } + else if(StatevectorMap.containsKey($var.text)){ + $value = StatevectorMap.get($var.text); + $expr = VarNodeMap.get($var.text); + } + else if(GlobalVarHashMap.containsKey($var.text)){ + $value = StatevectorMap.get($var.text); + $expr = VarNodeMap.get($var.text); + } + else if(VarNodeMap.containsKey($var.text)){ + System.err.println("error on line " + $var.getLine() + ": variable " + $var.text + " is an array"); + System.exit(1); + } + else{ + System.err.println("error on line " + $var.getLine() + ": variable " + $var.text + " is not valid"); + System.exit(1); + } + } + | (array=ID + { + List indexList = new ArrayList(); + List valueList = new ArrayList(); + VarNode arrayNode = null; + + if(!VarNodeMap.containsKey($array.text)){ + System.err.println("error on line " + $array.getLine() + ": " + $array.text + " is not a valid array"); + System.exit(1); + } + + arrayNode = VarNodeMap.get($array.text); + if(!ArrayNode.class.isAssignableFrom(arrayNode.getClass())){ + System.err.println("error on line " + $array.getLine() + ": " + $array.text + " is not a valid array"); + System.exit(1); + } + } + ('[' (arrayExpr=expression + { + ExpressionNode node = $arrayExpr.expr; + indexList.add(node); + valueList.add($arrayExpr.value); + } + ) ']')+ + { + String name = ((ArrayNode) arrayNode).getElement(valueList).getName(); + $value = StatevectorMap.get(name); + $expr = new ArrayElement((ArrayNode) arrayNode, indexList); + } + ) + | LPAREN expression RPAREN {$expr = $expression.expr; $value = $expression.value;} + | INT {$value = Integer.parseInt($INT.text); $expr = new ConstNode("name", $value);} + | TRUE {$expr = ONE; $value = 1;} + | FALSE {$expr = ZERO; $value = 0;} + ; + +unary returns [ExpressionNode expr, int value] + : {boolean positive = true;} + ('+' | ('-' {if(positive){ positive = false;} else {positive = true;}}))* term + { + if(!positive){ + $expr = new MinNode($term.expr); + $value = -$term.value; + } + else{ + $expr = $term.expr; + $value = $term.value; + } + } + ; + +bitwiseNegation returns [ExpressionNode expr, int value] + : {boolean neg = false;} + ('~' {if(neg){neg = false;} else{neg = true;}})* unary + { + if(neg){ + $expr = new BitNegNode($unary.expr); + $value = ~$unary.value; + } + else{ + $expr = $unary.expr; + $value = $unary.value; + } + } + ; + +negation returns [ExpressionNode expr, int value] + : {boolean neg = false;} + ('!' {if(neg){neg = false;} else{neg = true;}})* bitwiseNegation + { + if(neg){ + $expr = new NegNode($bitwiseNegation.expr); + $value = $bitwiseNegation.value == 0 ? 1 : 0; + } + else{ + $expr = $bitwiseNegation.expr; + $value = $bitwiseNegation.value; + } + } + ; + +mult returns [ExpressionNode expr, int value] + : op1=negation {$expr = $op1.expr; $value = $op1.value;} + ( '*' op2=negation {$expr = new MultNode($expr, $op2.expr); $value = $value * $op2.value;} + | '/' op2=negation {$expr = new DivNode($expr, $op2.expr); $value = $value / $op2.value;} + | '%' op2=negation {$expr = new ModNode($expr, $op2.expr); $value = $value \% $op2.value;} + )* + ; + +add returns [ExpressionNode expr, int value] + : op1=mult {$expr = $op1.expr; $value = $op1.value;} + ( '+' op2=mult {$expr = new AddNode($expr, $op2.expr); $value = $value + $op2.value;} + | '-' op2=mult {$expr = new SubNode($expr, $op2.expr); $value = $value - $op2.value;} + )* + ; + +shift returns [ExpressionNode expr, int value] + : op1=add {$expr = $op1.expr; $value = $op1.value;} + ( '<<' op2=add {$expr = new LeftShiftNode($expr, $op2.expr); $value = $value << $op2.value;} + | '>>' op2=add {$expr = new RightShiftNode($expr, $op2.expr); $value = $value >> $op2.value;} + )* + ; + +relation returns [ExpressionNode expr, int value] + : op1=shift {$expr = $op1.expr; $value = $op1.value;} + ( '<' op2=shift {$expr = new LessNode($expr, $op2.expr); $value = ($value < $op2.value) ? 1 : 0;} + | '<=' op2=shift {$expr = new LessEqualNode($expr, $op2.expr); $value = ($value <= $op2.value) ? 1 : 0;} + | '>=' op2=shift {$expr = new GreatEqualNode($expr, $op2.expr); $value = ($value >= $op2.value) ? 1 : 0;} + | '>' op2=shift {$expr = new GreatNode($expr, $op2.expr); $value = ($value > $op2.value) ? 1 : 0;} + )* + ; + +equivalence returns [ExpressionNode expr, int value] + : op1=relation {$expr = $op1.expr; $value = $op1.value;} + ( '==' op2=relation {$expr = new EquivNode($expr, $op2.expr); $value = ($value == $op2.value) ? 1 : 0;} + | '!=' op2=relation {$expr = new NotEquivNode($expr, $op2.expr); $value = ($value != $op2.value) ? 1 : 0;} + )* + ; + +bitwiseAnd returns [ExpressionNode expr, int value] + : op1=equivalence {$expr = $op1.expr; $value = $op1.value;} + ( '&' op2=equivalence {$expr = new BitAndNode($expr, $op2.expr); $value = $value & $op2.value;} + )* + ; + +bitwiseXor returns [ExpressionNode expr, int value] + : op1=bitwiseAnd {$expr = $op1.expr; $value = $op1.value;} + ( '^' op2=bitwiseAnd {$expr = new BitXorNode($expr, $op2.expr); $value = $value ^ $op2.value;} + )* + ; + +bitwiseOr returns [ExpressionNode expr, int value] + : op1=bitwiseXor {$expr = $op1.expr; $value = $op1.value;} + ( '|' op2=bitwiseXor {$expr = new BitOrNode($expr, $op2.expr); $value = $value | $op2.value;} + )* + ; + +and returns [ExpressionNode expr, int value] + : op1=bitwiseOr {$expr = $op1.expr; $value = $op1.value;} + ( '&&' op2=bitwiseOr {$expr = new AndNode($expr, $op2.expr); $value = ($value != 0 && $op2.value != 0) ? 1 : 0;} + )* + ; + +or returns [ExpressionNode expr, int value] + : op1=and {$expr = $op1.expr; $value = $op1.value;} + ( '||' op2=and {$expr = new OrNode($expr, $op2.expr); $value = ($value != 0 || $op2.value != 0) ? 1 : 0;} + )* + ; + +implication returns [ExpressionNode expr, int value] + : op1=or {$expr = $op1.expr; $value = $op1.value;} + ( '->' op2=or {$expr = new ImplicationNode($expr, $op2.expr); $value = ($value == 0 || $op2.value != 0) ? 1 : 0;} + )* + ; + +expression returns [ExpressionNode expr, int value] + : op1=implication {$expr = $op1.expr; $value = $op1.value;} + ('?' op2=expression ':' op3=expression + { + $value = ($value != 0) ? $op2.value : $op3.value; + $expr = new TernaryNode($expr, $op2.expr, $op3.expr); + } + )? + ; + +//CTL formula +ctlTerm + : ID + | LPAREN ctl LPAREN + ; + +ctl + : + ; + + +// Tokens +LPAREN: '('; +RPAREN: ')'; +QMARK: '?'; +COLON: ':'; +SEMICOLON: ';'; +PERIOD: '.'; +UNDERSCORE: '_'; +COMMA: ','; +QUOTE: '"'; + +// Reserved Words +MODULE: 'mod'; +NAME: 'name'; +INPUT: 'input'; +OUTPUT: 'output'; +INTERNAL: 'var'; +MARKING: 'marking'; +STATE_VECTOR: 'statevector'; +TRANSITION: 'transition'; +LABEL: 'label'; +PRESET: 'preset'; +POSTSET: 'postset'; +TRUE: 'true'; +FALSE: 'false'; + +// Arithmetic Operators +PLUS: '+'; +MINUS: '-'; +TIMES: '*'; +DIV: '/'; +MOD: '%'; +EQUALS: '='; + +// Comparison Operators +GREATER: '>'; +LESS: '<'; +GREATER_EQUAL: '>='; +LESS_EQUAL: '<='; +EQUIV: '=='; +NOT_EQUIV: '!='; + +// Logical Operators +NEGATION: '!'; +AND: '&&'; +OR: '||'; +IMPLICATION: '->'; + +// Bitwise Operators +BITWISE_NEGATION: '~'; +BITWISE_AND: '&'; +BITWISE_OR: '|'; +BITWISE_XOR: '^'; +BITWISE_LSHIFT: '<<'; +BITWISE_RSHIFT: '>>'; + +//CLOSE_INCLUDE : '<' '/include' '>'; +//CLOSE_CONST : '<' '/const' '>'; +//CLOSE_VAR : '<' '/var' '>'; +//CLOSE_MODULE : '<' '/mod' '>'; +//CLOSE_CLASS : '<' '/class' '>'; +//CLOSE_MARKING : '<' '/marking' '>'; +//CLOSE_TRANSITION : '<' '/transition' '>'; + +fragment LETTER: ('a'..'z' | 'A'..'Z'); +fragment DIGIT: '0'..'9'; +fragment FILE: (LETTER | DIGIT) ('_'? (LETTER | DIGIT))*; +INT: '-'? DIGIT+; +ID: LETTER (UNDERSCORE? (LETTER | DIGIT))*; +PATH: ((LETTER ':') | '/')? (FILE ('/' | '\\'))* FILE '.lpn'; +MEMBER: ID '.' ID; +WS: (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel = HIDDEN;}; +COMMENT: '//' .* ('\n' | '\r') {$channel = HIDDEN;}; +MULTILINECOMMENT: '/*' .* '*/' {$channel = HIDDEN;}; +XMLCOMMENT: ('<' '!' '-' '-') .* ('-' '-' '>') {$channel = HIDDEN;}; +IGNORE: '<' '?' .* '?' '>' {$channel = HIDDEN;}; + diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuInstLexer.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuInstLexer.java new file mode 100644 index 000000000..0d78fb6f1 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/PlatuInstLexer.java @@ -0,0 +1,3258 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +// $ANTLR 3.3 Nov 30, 2010 12:50:56 /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g 2011-09-05 15:36:31 + + package edu.utah.ece.async.lema.verification.platu.platuLpn.io; + + +import org.antlr.runtime.*; + +public class PlatuInstLexer extends Lexer { + public static final int EOF=-1; + public static final int T__60=60; + public static final int T__61=61; + public static final int T__62=62; + public static final int T__63=63; + public static final int T__64=64; + public static final int T__65=65; + public static final int T__66=66; + public static final int T__67=67; + public static final int T__68=68; + public static final int T__69=69; + public static final int T__70=70; + public static final int T__71=71; + public static final int T__72=72; + public static final int T__73=73; + public static final int T__74=74; + public static final int T__75=75; + public static final int T__76=76; + public static final int T__77=77; + public static final int T__78=78; + public static final int T__79=79; + public static final int T__80=80; + public static final int T__81=81; + public static final int PATH=4; + public static final int ID=5; + public static final int INT=6; + public static final int MEMBER=7; + public static final int LPAREN=8; + public static final int RPAREN=9; + public static final int TRUE=10; + public static final int FALSE=11; + public static final int QMARK=12; + public static final int COLON=13; + public static final int SEMICOLON=14; + public static final int PERIOD=15; + public static final int UNDERSCORE=16; + public static final int COMMA=17; + public static final int QUOTE=18; + public static final int MODULE=19; + public static final int NAME=20; + public static final int INPUT=21; + public static final int OUTPUT=22; + public static final int INTERNAL=23; + public static final int MARKING=24; + public static final int STATE_VECTOR=25; + public static final int TRANSITION=26; + public static final int LABEL=27; + public static final int PRESET=28; + public static final int POSTSET=29; + public static final int PLUS=30; + public static final int MINUS=31; + public static final int TIMES=32; + public static final int DIV=33; + public static final int MOD=34; + public static final int EQUALS=35; + public static final int GREATER=36; + public static final int LESS=37; + public static final int GREATER_EQUAL=38; + public static final int LESS_EQUAL=39; + public static final int EQUIV=40; + public static final int NOT_EQUIV=41; + public static final int NEGATION=42; + public static final int AND=43; + public static final int OR=44; + public static final int IMPLICATION=45; + public static final int BITWISE_NEGATION=46; + public static final int BITWISE_AND=47; + public static final int BITWISE_OR=48; + public static final int BITWISE_XOR=49; + public static final int BITWISE_LSHIFT=50; + public static final int BITWISE_RSHIFT=51; + public static final int LETTER=52; + public static final int DIGIT=53; + public static final int FILE=54; + public static final int WS=55; + public static final int COMMENT=56; + public static final int MULTILINECOMMENT=57; + public static final int XMLCOMMENT=58; + public static final int IGNORE=59; + + // delegates + // delegators + + public PlatuInstLexer() {} + public PlatuInstLexer(CharStream input) { + this(input, new RecognizerSharedState()); + } + public PlatuInstLexer(CharStream input, RecognizerSharedState state) { + super(input,state); + + } + @Override + public String getGrammarFileName() { return "/Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g"; } + + // $ANTLR start "T__60" + public final void mT__60() throws RecognitionException { + try { + int _type = T__60; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:11:7: ( 'include' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:11:9: 'include' + { + match("include"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__60" + + // $ANTLR start "T__61" + public final void mT__61() throws RecognitionException { + try { + int _type = T__61; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:12:7: ( '/include' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:12:9: '/include' + { + match("/include"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__61" + + // $ANTLR start "T__62" + public final void mT__62() throws RecognitionException { + try { + int _type = T__62; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:13:7: ( 'main' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:13:9: 'main' + { + match("main"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__62" + + // $ANTLR start "T__63" + public final void mT__63() throws RecognitionException { + try { + int _type = T__63; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:14:7: ( '/mod' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:14:9: '/mod' + { + match("/mod"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__63" + + // $ANTLR start "T__64" + public final void mT__64() throws RecognitionException { + try { + int _type = T__64; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:15:7: ( 'process' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:15:9: 'process' + { + match("process"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__64" + + // $ANTLR start "T__65" + public final void mT__65() throws RecognitionException { + try { + int _type = T__65; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:16:7: ( '/process' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:16:9: '/process' + { + match("/process"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__65" + + // $ANTLR start "T__66" + public final void mT__66() throws RecognitionException { + try { + int _type = T__66; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:17:7: ( 'class' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:17:9: 'class' + { + match("class"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__66" + + // $ANTLR start "T__67" + public final void mT__67() throws RecognitionException { + try { + int _type = T__67; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:18:7: ( 'arg' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:18:9: 'arg' + { + match("arg"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__67" + + // $ANTLR start "T__68" + public final void mT__68() throws RecognitionException { + try { + int _type = T__68; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:19:7: ( '[' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:19:9: '[' + { + match('['); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__68" + + // $ANTLR start "T__69" + public final void mT__69() throws RecognitionException { + try { + int _type = T__69; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:20:7: ( ']' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:20:9: ']' + { + match(']'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__69" + + // $ANTLR start "T__70" + public final void mT__70() throws RecognitionException { + try { + int _type = T__70; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:21:7: ( '/class' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:21:9: '/class' + { + match("/class"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__70" + + // $ANTLR start "T__71" + public final void mT__71() throws RecognitionException { + try { + int _type = T__71; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:22:7: ( 'const' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:22:9: 'const' + { + match("const"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__71" + + // $ANTLR start "T__72" + public final void mT__72() throws RecognitionException { + try { + int _type = T__72; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:23:7: ( '/const' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:23:9: '/const' + { + match("/const"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__72" + + // $ANTLR start "T__73" + public final void mT__73() throws RecognitionException { + try { + int _type = T__73; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:24:7: ( '/var' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:24:9: '/var' + { + match("/var"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__73" + + // $ANTLR start "T__74" + public final void mT__74() throws RecognitionException { + try { + int _type = T__74; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:25:7: ( '{' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:25:9: '{' + { + match('{'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__74" + + // $ANTLR start "T__75" + public final void mT__75() throws RecognitionException { + try { + int _type = T__75; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:26:7: ( '}' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:26:9: '}' + { + match('}'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__75" + + // $ANTLR start "T__76" + public final void mT__76() throws RecognitionException { + try { + int _type = T__76; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:27:7: ( '/marking' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:27:9: '/marking' + { + match("/marking"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__76" + + // $ANTLR start "T__77" + public final void mT__77() throws RecognitionException { + try { + int _type = T__77; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:28:7: ( '/transition' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:28:9: '/transition' + { + match("/transition"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__77" + + // $ANTLR start "T__78" + public final void mT__78() throws RecognitionException { + try { + int _type = T__78; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:29:7: ( 'assert' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:29:9: 'assert' + { + match("assert"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__78" + + // $ANTLR start "T__79" + public final void mT__79() throws RecognitionException { + try { + int _type = T__79; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:30:7: ( 'condition' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:30:9: 'condition' + { + match("condition"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__79" + + // $ANTLR start "T__80" + public final void mT__80() throws RecognitionException { + try { + int _type = T__80; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:31:7: ( 'delay' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:31:9: 'delay' + { + match("delay"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__80" + + // $ANTLR start "T__81" + public final void mT__81() throws RecognitionException { + try { + int _type = T__81; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:32:7: ( 'inf' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:32:9: 'inf' + { + match("inf"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "T__81" + + // $ANTLR start "LPAREN" + public final void mLPAREN() throws RecognitionException { + try { + int _type = LPAREN; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1426:7: ( '(' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1426:9: '(' + { + match('('); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "LPAREN" + + // $ANTLR start "RPAREN" + public final void mRPAREN() throws RecognitionException { + try { + int _type = RPAREN; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1427:7: ( ')' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1427:9: ')' + { + match(')'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "RPAREN" + + // $ANTLR start "QMARK" + public final void mQMARK() throws RecognitionException { + try { + int _type = QMARK; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1428:6: ( '?' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1428:8: '?' + { + match('?'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "QMARK" + + // $ANTLR start "COLON" + public final void mCOLON() throws RecognitionException { + try { + int _type = COLON; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1429:6: ( ':' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1429:8: ':' + { + match(':'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "COLON" + + // $ANTLR start "SEMICOLON" + public final void mSEMICOLON() throws RecognitionException { + try { + int _type = SEMICOLON; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1430:10: ( ';' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1430:12: ';' + { + match(';'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "SEMICOLON" + + // $ANTLR start "PERIOD" + public final void mPERIOD() throws RecognitionException { + try { + int _type = PERIOD; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1431:7: ( '.' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1431:9: '.' + { + match('.'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "PERIOD" + + // $ANTLR start "UNDERSCORE" + public final void mUNDERSCORE() throws RecognitionException { + try { + int _type = UNDERSCORE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1432:11: ( '_' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1432:13: '_' + { + match('_'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "UNDERSCORE" + + // $ANTLR start "COMMA" + public final void mCOMMA() throws RecognitionException { + try { + int _type = COMMA; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1433:6: ( ',' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1433:8: ',' + { + match(','); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "COMMA" + + // $ANTLR start "QUOTE" + public final void mQUOTE() throws RecognitionException { + try { + int _type = QUOTE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1434:6: ( '\"' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1434:8: '\"' + { + match('\"'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "QUOTE" + + // $ANTLR start "MODULE" + public final void mMODULE() throws RecognitionException { + try { + int _type = MODULE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1437:7: ( 'mod' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1437:9: 'mod' + { + match("mod"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "MODULE" + + // $ANTLR start "NAME" + public final void mNAME() throws RecognitionException { + try { + int _type = NAME; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1438:5: ( 'name' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1438:7: 'name' + { + match("name"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "NAME" + + // $ANTLR start "INPUT" + public final void mINPUT() throws RecognitionException { + try { + int _type = INPUT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1439:6: ( 'input' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1439:8: 'input' + { + match("input"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "INPUT" + + // $ANTLR start "OUTPUT" + public final void mOUTPUT() throws RecognitionException { + try { + int _type = OUTPUT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1440:7: ( 'output' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1440:9: 'output' + { + match("output"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "OUTPUT" + + // $ANTLR start "INTERNAL" + public final void mINTERNAL() throws RecognitionException { + try { + int _type = INTERNAL; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1441:9: ( 'var' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1441:11: 'var' + { + match("var"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "INTERNAL" + + // $ANTLR start "MARKING" + public final void mMARKING() throws RecognitionException { + try { + int _type = MARKING; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1442:8: ( 'marking' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1442:10: 'marking' + { + match("marking"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "MARKING" + + // $ANTLR start "STATE_VECTOR" + public final void mSTATE_VECTOR() throws RecognitionException { + try { + int _type = STATE_VECTOR; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1443:13: ( 'statevector' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1443:15: 'statevector' + { + match("statevector"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "STATE_VECTOR" + + // $ANTLR start "TRANSITION" + public final void mTRANSITION() throws RecognitionException { + try { + int _type = TRANSITION; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1444:11: ( 'transition' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1444:13: 'transition' + { + match("transition"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "TRANSITION" + + // $ANTLR start "LABEL" + public final void mLABEL() throws RecognitionException { + try { + int _type = LABEL; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1445:6: ( 'label' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1445:8: 'label' + { + match("label"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "LABEL" + + // $ANTLR start "PRESET" + public final void mPRESET() throws RecognitionException { + try { + int _type = PRESET; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1446:7: ( 'preset' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1446:9: 'preset' + { + match("preset"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "PRESET" + + // $ANTLR start "POSTSET" + public final void mPOSTSET() throws RecognitionException { + try { + int _type = POSTSET; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1447:8: ( 'postset' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1447:10: 'postset' + { + match("postset"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "POSTSET" + + // $ANTLR start "TRUE" + public final void mTRUE() throws RecognitionException { + try { + int _type = TRUE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1448:5: ( 'true' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1448:7: 'true' + { + match("true"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "TRUE" + + // $ANTLR start "FALSE" + public final void mFALSE() throws RecognitionException { + try { + int _type = FALSE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1449:6: ( 'false' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1449:8: 'false' + { + match("false"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "FALSE" + + // $ANTLR start "PLUS" + public final void mPLUS() throws RecognitionException { + try { + int _type = PLUS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1452:5: ( '+' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1452:7: '+' + { + match('+'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "PLUS" + + // $ANTLR start "MINUS" + public final void mMINUS() throws RecognitionException { + try { + int _type = MINUS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1453:6: ( '-' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1453:8: '-' + { + match('-'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "MINUS" + + // $ANTLR start "TIMES" + public final void mTIMES() throws RecognitionException { + try { + int _type = TIMES; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1454:6: ( '*' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1454:8: '*' + { + match('*'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "TIMES" + + // $ANTLR start "DIV" + public final void mDIV() throws RecognitionException { + try { + int _type = DIV; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1455:4: ( '/' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1455:6: '/' + { + match('/'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "DIV" + + // $ANTLR start "MOD" + public final void mMOD() throws RecognitionException { + try { + int _type = MOD; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1456:4: ( '%' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1456:6: '%' + { + match('%'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "MOD" + + // $ANTLR start "EQUALS" + public final void mEQUALS() throws RecognitionException { + try { + int _type = EQUALS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1457:7: ( '=' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1457:9: '=' + { + match('='); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "EQUALS" + + // $ANTLR start "GREATER" + public final void mGREATER() throws RecognitionException { + try { + int _type = GREATER; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1460:8: ( '>' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1460:10: '>' + { + match('>'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "GREATER" + + // $ANTLR start "LESS" + public final void mLESS() throws RecognitionException { + try { + int _type = LESS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1461:5: ( '<' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1461:7: '<' + { + match('<'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "LESS" + + // $ANTLR start "GREATER_EQUAL" + public final void mGREATER_EQUAL() throws RecognitionException { + try { + int _type = GREATER_EQUAL; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1462:14: ( '>=' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1462:16: '>=' + { + match(">="); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "GREATER_EQUAL" + + // $ANTLR start "LESS_EQUAL" + public final void mLESS_EQUAL() throws RecognitionException { + try { + int _type = LESS_EQUAL; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1463:11: ( '<=' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1463:13: '<=' + { + match("<="); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "LESS_EQUAL" + + // $ANTLR start "EQUIV" + public final void mEQUIV() throws RecognitionException { + try { + int _type = EQUIV; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1464:6: ( '==' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1464:8: '==' + { + match("=="); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "EQUIV" + + // $ANTLR start "NOT_EQUIV" + public final void mNOT_EQUIV() throws RecognitionException { + try { + int _type = NOT_EQUIV; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1465:10: ( '!=' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1465:12: '!=' + { + match("!="); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "NOT_EQUIV" + + // $ANTLR start "NEGATION" + public final void mNEGATION() throws RecognitionException { + try { + int _type = NEGATION; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1468:9: ( '!' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1468:11: '!' + { + match('!'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "NEGATION" + + // $ANTLR start "AND" + public final void mAND() throws RecognitionException { + try { + int _type = AND; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1469:4: ( '&&' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1469:6: '&&' + { + match("&&"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "AND" + + // $ANTLR start "OR" + public final void mOR() throws RecognitionException { + try { + int _type = OR; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1470:3: ( '||' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1470:5: '||' + { + match("||"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "OR" + + // $ANTLR start "IMPLICATION" + public final void mIMPLICATION() throws RecognitionException { + try { + int _type = IMPLICATION; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1471:12: ( '->' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1471:14: '->' + { + match("->"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "IMPLICATION" + + // $ANTLR start "BITWISE_NEGATION" + public final void mBITWISE_NEGATION() throws RecognitionException { + try { + int _type = BITWISE_NEGATION; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1474:17: ( '~' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1474:19: '~' + { + match('~'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "BITWISE_NEGATION" + + // $ANTLR start "BITWISE_AND" + public final void mBITWISE_AND() throws RecognitionException { + try { + int _type = BITWISE_AND; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1475:12: ( '&' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1475:14: '&' + { + match('&'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "BITWISE_AND" + + // $ANTLR start "BITWISE_OR" + public final void mBITWISE_OR() throws RecognitionException { + try { + int _type = BITWISE_OR; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1476:11: ( '|' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1476:13: '|' + { + match('|'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "BITWISE_OR" + + // $ANTLR start "BITWISE_XOR" + public final void mBITWISE_XOR() throws RecognitionException { + try { + int _type = BITWISE_XOR; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1477:12: ( '^' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1477:14: '^' + { + match('^'); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "BITWISE_XOR" + + // $ANTLR start "BITWISE_LSHIFT" + public final void mBITWISE_LSHIFT() throws RecognitionException { + try { + int _type = BITWISE_LSHIFT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1478:15: ( '<<' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1478:17: '<<' + { + match("<<"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "BITWISE_LSHIFT" + + // $ANTLR start "BITWISE_RSHIFT" + public final void mBITWISE_RSHIFT() throws RecognitionException { + try { + int _type = BITWISE_RSHIFT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1479:15: ( '>>' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1479:17: '>>' + { + match(">>"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "BITWISE_RSHIFT" + + // $ANTLR start "LETTER" + public final void mLETTER() throws RecognitionException { + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1489:16: ( ( 'a' .. 'z' | 'A' .. 'Z' ) ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1489:18: ( 'a' .. 'z' | 'A' .. 'Z' ) + { + if ( (input.LA(1)>='A' && input.LA(1)<='Z')||(input.LA(1)>='a' && input.LA(1)<='z') ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + + } + finally { + } + } + // $ANTLR end "LETTER" + + // $ANTLR start "DIGIT" + public final void mDIGIT() throws RecognitionException { + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1490:15: ( '0' .. '9' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1490:17: '0' .. '9' + { + matchRange('0','9'); + + } + + } + finally { + } + } + // $ANTLR end "DIGIT" + + // $ANTLR start "FILE" + public final void mFILE() throws RecognitionException { + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1491:14: ( ( LETTER | DIGIT ) ( ( '_' )? ( LETTER | DIGIT ) )* ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1491:16: ( LETTER | DIGIT ) ( ( '_' )? ( LETTER | DIGIT ) )* + { + if ( (input.LA(1)>='0' && input.LA(1)<='9')||(input.LA(1)>='A' && input.LA(1)<='Z')||(input.LA(1)>='a' && input.LA(1)<='z') ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1491:33: ( ( '_' )? ( LETTER | DIGIT ) )* + loop2: + do { + int alt2=2; + int LA2_0 = input.LA(1); + + if ( ((LA2_0>='0' && LA2_0<='9')||(LA2_0>='A' && LA2_0<='Z')||LA2_0=='_'||(LA2_0>='a' && LA2_0<='z')) ) { + alt2=1; + } + + + switch (alt2) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1491:34: ( '_' )? ( LETTER | DIGIT ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1491:34: ( '_' )? + int alt1=2; + int LA1_0 = input.LA(1); + + if ( (LA1_0=='_') ) { + alt1=1; + } + switch (alt1) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1491:34: '_' + { + match('_'); + + } + break; + + } + + if ( (input.LA(1)>='0' && input.LA(1)<='9')||(input.LA(1)>='A' && input.LA(1)<='Z')||(input.LA(1)>='a' && input.LA(1)<='z') ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + break; + + default : + break loop2; + } + } while (true); + + + } + + } + finally { + } + } + // $ANTLR end "FILE" + + // $ANTLR start "INT" + public final void mINT() throws RecognitionException { + try { + int _type = INT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1492:4: ( ( '-' )? ( DIGIT )+ ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1492:6: ( '-' )? ( DIGIT )+ + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1492:6: ( '-' )? + int alt3=2; + int LA3_0 = input.LA(1); + + if ( (LA3_0=='-') ) { + alt3=1; + } + switch (alt3) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1492:6: '-' + { + match('-'); + + } + break; + + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1492:11: ( DIGIT )+ + int cnt4=0; + loop4: + do { + int alt4=2; + int LA4_0 = input.LA(1); + + if ( ((LA4_0>='0' && LA4_0<='9')) ) { + alt4=1; + } + + + switch (alt4) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1492:11: DIGIT + { + mDIGIT(); + + } + break; + + default : + if ( cnt4 >= 1 ) break loop4; + EarlyExitException eee = + new EarlyExitException(4, input); + throw eee; + } + cnt4++; + } while (true); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "INT" + + // $ANTLR start "ID" + public final void mID() throws RecognitionException { + try { + int _type = ID; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1493:3: ( LETTER ( ( UNDERSCORE )? ( LETTER | DIGIT ) )* ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1493:5: LETTER ( ( UNDERSCORE )? ( LETTER | DIGIT ) )* + { + mLETTER(); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1493:12: ( ( UNDERSCORE )? ( LETTER | DIGIT ) )* + loop6: + do { + int alt6=2; + int LA6_0 = input.LA(1); + + if ( ((LA6_0>='0' && LA6_0<='9')||(LA6_0>='A' && LA6_0<='Z')||LA6_0=='_'||(LA6_0>='a' && LA6_0<='z')) ) { + alt6=1; + } + + + switch (alt6) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1493:13: ( UNDERSCORE )? ( LETTER | DIGIT ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1493:13: ( UNDERSCORE )? + int alt5=2; + int LA5_0 = input.LA(1); + + if ( (LA5_0=='_') ) { + alt5=1; + } + switch (alt5) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1493:13: UNDERSCORE + { + mUNDERSCORE(); + + } + break; + + } + + if ( (input.LA(1)>='0' && input.LA(1)<='9')||(input.LA(1)>='A' && input.LA(1)<='Z')||(input.LA(1)>='a' && input.LA(1)<='z') ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + break; + + default : + break loop6; + } + } while (true); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "ID" + + // $ANTLR start "PATH" + public final void mPATH() throws RecognitionException { + try { + int _type = PATH; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1494:5: ( ( ( LETTER ':' ) | '/' )? ( FILE ( '/' | '\\\\' ) )* FILE '.lpn' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1494:7: ( ( LETTER ':' ) | '/' )? ( FILE ( '/' | '\\\\' ) )* FILE '.lpn' + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1494:7: ( ( LETTER ':' ) | '/' )? + int alt7=3; + int LA7_0 = input.LA(1); + + if ( ((LA7_0>='A' && LA7_0<='Z')||(LA7_0>='a' && LA7_0<='z')) ) { + int LA7_1 = input.LA(2); + + if ( (LA7_1==':') ) { + alt7=1; + } + } + else if ( (LA7_0=='/') ) { + alt7=2; + } + switch (alt7) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1494:8: ( LETTER ':' ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1494:8: ( LETTER ':' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1494:9: LETTER ':' + { + mLETTER(); + match(':'); + + } + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1494:23: '/' + { + match('/'); + + } + break; + + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1494:29: ( FILE ( '/' | '\\\\' ) )* + loop8: + do { + int alt8=2; + alt8 = dfa8.predict(input); + switch (alt8) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1494:30: FILE ( '/' | '\\\\' ) + { + mFILE(); + if ( input.LA(1)=='/'||input.LA(1)=='\\' ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + break; + + default : + break loop8; + } + } while (true); + + mFILE(); + match(".lpn"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "PATH" + + // $ANTLR start "MEMBER" + public final void mMEMBER() throws RecognitionException { + try { + int _type = MEMBER; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1495:7: ( ID '.' ID ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1495:9: ID '.' ID + { + mID(); + match('.'); + mID(); + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "MEMBER" + + // $ANTLR start "WS" + public final void mWS() throws RecognitionException { + try { + int _type = WS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1496:3: ( ( ' ' | '\\t' | '\\n' | '\\r' | '\\f' )+ ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1496:5: ( ' ' | '\\t' | '\\n' | '\\r' | '\\f' )+ + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1496:5: ( ' ' | '\\t' | '\\n' | '\\r' | '\\f' )+ + int cnt9=0; + loop9: + do { + int alt9=2; + int LA9_0 = input.LA(1); + + if ( ((LA9_0>='\t' && LA9_0<='\n')||(LA9_0>='\f' && LA9_0<='\r')||LA9_0==' ') ) { + alt9=1; + } + + + switch (alt9) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g: + { + if ( (input.LA(1)>='\t' && input.LA(1)<='\n')||(input.LA(1)>='\f' && input.LA(1)<='\r')||input.LA(1)==' ' ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + + } + break; + + default : + if ( cnt9 >= 1 ) break loop9; + EarlyExitException eee = + new EarlyExitException(9, input); + throw eee; + } + cnt9++; + } while (true); + + _channel = HIDDEN; + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "WS" + + // $ANTLR start "COMMENT" + public final void mCOMMENT() throws RecognitionException { + try { + int _type = COMMENT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1497:8: ( '//' ( . )* ( '\\n' | '\\r' ) ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1497:10: '//' ( . )* ( '\\n' | '\\r' ) + { + match("//"); + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1497:15: ( . )* + loop10: + do { + int alt10=2; + int LA10_0 = input.LA(1); + + if ( (LA10_0=='\n'||LA10_0=='\r') ) { + alt10=2; + } + else if ( ((LA10_0>='\u0000' && LA10_0<='\t')||(LA10_0>='\u000B' && LA10_0<='\f')||(LA10_0>='\u000E' && LA10_0<='\uFFFF')) ) { + alt10=1; + } + + + switch (alt10) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1497:15: . + { + matchAny(); + + } + break; + + default : + break loop10; + } + } while (true); + + if ( input.LA(1)=='\n'||input.LA(1)=='\r' ) { + input.consume(); + + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + recover(mse); + throw mse;} + + _channel = HIDDEN; + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "COMMENT" + + // $ANTLR start "MULTILINECOMMENT" + public final void mMULTILINECOMMENT() throws RecognitionException { + try { + int _type = MULTILINECOMMENT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1498:17: ( '/*' ( . )* '*/' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1498:19: '/*' ( . )* '*/' + { + match("/*"); + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1498:24: ( . )* + loop11: + do { + int alt11=2; + int LA11_0 = input.LA(1); + + if ( (LA11_0=='*') ) { + int LA11_1 = input.LA(2); + + if ( (LA11_1=='/') ) { + alt11=2; + } + else if ( ((LA11_1>='\u0000' && LA11_1<='.')||(LA11_1>='0' && LA11_1<='\uFFFF')) ) { + alt11=1; + } + + + } + else if ( ((LA11_0>='\u0000' && LA11_0<=')')||(LA11_0>='+' && LA11_0<='\uFFFF')) ) { + alt11=1; + } + + + switch (alt11) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1498:24: . + { + matchAny(); + + } + break; + + default : + break loop11; + } + } while (true); + + match("*/"); + + _channel = HIDDEN; + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "MULTILINECOMMENT" + + // $ANTLR start "XMLCOMMENT" + public final void mXMLCOMMENT() throws RecognitionException { + try { + int _type = XMLCOMMENT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1499:11: ( ( '<' '!' '-' '-' ) ( . )* ( '-' '-' '>' ) ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1499:13: ( '<' '!' '-' '-' ) ( . )* ( '-' '-' '>' ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1499:13: ( '<' '!' '-' '-' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1499:14: '<' '!' '-' '-' + { + match('<'); + match('!'); + match('-'); + match('-'); + + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1499:31: ( . )* + loop12: + do { + int alt12=2; + int LA12_0 = input.LA(1); + + if ( (LA12_0=='-') ) { + int LA12_1 = input.LA(2); + + if ( (LA12_1=='-') ) { + int LA12_3 = input.LA(3); + + if ( (LA12_3=='>') ) { + alt12=2; + } + else if ( ((LA12_3>='\u0000' && LA12_3<='=')||(LA12_3>='?' && LA12_3<='\uFFFF')) ) { + alt12=1; + } + + + } + else if ( ((LA12_1>='\u0000' && LA12_1<=',')||(LA12_1>='.' && LA12_1<='\uFFFF')) ) { + alt12=1; + } + + + } + else if ( ((LA12_0>='\u0000' && LA12_0<=',')||(LA12_0>='.' && LA12_0<='\uFFFF')) ) { + alt12=1; + } + + + switch (alt12) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1499:31: . + { + matchAny(); + + } + break; + + default : + break loop12; + } + } while (true); + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1499:34: ( '-' '-' '>' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1499:35: '-' '-' '>' + { + match('-'); + match('-'); + match('>'); + + } + + _channel = HIDDEN; + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "XMLCOMMENT" + + // $ANTLR start "IGNORE" + public final void mIGNORE() throws RecognitionException { + try { + int _type = IGNORE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1500:7: ( '<' '?' ( . )* '?' '>' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1500:9: '<' '?' ( . )* '?' '>' + { + match('<'); + match('?'); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1500:17: ( . )* + loop13: + do { + int alt13=2; + int LA13_0 = input.LA(1); + + if ( (LA13_0=='?') ) { + int LA13_1 = input.LA(2); + + if ( (LA13_1=='>') ) { + alt13=2; + } + else if ( ((LA13_1>='\u0000' && LA13_1<='=')||(LA13_1>='?' && LA13_1<='\uFFFF')) ) { + alt13=1; + } + + + } + else if ( ((LA13_0>='\u0000' && LA13_0<='>')||(LA13_0>='@' && LA13_0<='\uFFFF')) ) { + alt13=1; + } + + + switch (alt13) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1500:17: . + { + matchAny(); + + } + break; + + default : + break loop13; + } + } while (true); + + match('?'); + match('>'); + _channel = HIDDEN; + + } + + state.type = _type; + state.channel = _channel; + } + finally { + } + } + // $ANTLR end "IGNORE" + + @Override + public void mTokens() throws RecognitionException { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:8: ( T__60 | T__61 | T__62 | T__63 | T__64 | T__65 | T__66 | T__67 | T__68 | T__69 | T__70 | T__71 | T__72 | T__73 | T__74 | T__75 | T__76 | T__77 | T__78 | T__79 | T__80 | T__81 | LPAREN | RPAREN | QMARK | COLON | SEMICOLON | PERIOD | UNDERSCORE | COMMA | QUOTE | MODULE | NAME | INPUT | OUTPUT | INTERNAL | MARKING | STATE_VECTOR | TRANSITION | LABEL | PRESET | POSTSET | TRUE | FALSE | PLUS | MINUS | TIMES | DIV | MOD | EQUALS | GREATER | LESS | GREATER_EQUAL | LESS_EQUAL | EQUIV | NOT_EQUIV | NEGATION | AND | OR | IMPLICATION | BITWISE_NEGATION | BITWISE_AND | BITWISE_OR | BITWISE_XOR | BITWISE_LSHIFT | BITWISE_RSHIFT | INT | ID | PATH | MEMBER | WS | COMMENT | MULTILINECOMMENT | XMLCOMMENT | IGNORE ) + int alt14=75; + alt14 = dfa14.predict(input); + switch (alt14) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:10: T__60 + { + mT__60(); + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:16: T__61 + { + mT__61(); + + } + break; + case 3 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:22: T__62 + { + mT__62(); + + } + break; + case 4 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:28: T__63 + { + mT__63(); + + } + break; + case 5 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:34: T__64 + { + mT__64(); + + } + break; + case 6 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:40: T__65 + { + mT__65(); + + } + break; + case 7 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:46: T__66 + { + mT__66(); + + } + break; + case 8 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:52: T__67 + { + mT__67(); + + } + break; + case 9 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:58: T__68 + { + mT__68(); + + } + break; + case 10 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:64: T__69 + { + mT__69(); + + } + break; + case 11 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:70: T__70 + { + mT__70(); + + } + break; + case 12 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:76: T__71 + { + mT__71(); + + } + break; + case 13 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:82: T__72 + { + mT__72(); + + } + break; + case 14 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:88: T__73 + { + mT__73(); + + } + break; + case 15 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:94: T__74 + { + mT__74(); + + } + break; + case 16 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:100: T__75 + { + mT__75(); + + } + break; + case 17 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:106: T__76 + { + mT__76(); + + } + break; + case 18 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:112: T__77 + { + mT__77(); + + } + break; + case 19 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:118: T__78 + { + mT__78(); + + } + break; + case 20 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:124: T__79 + { + mT__79(); + + } + break; + case 21 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:130: T__80 + { + mT__80(); + + } + break; + case 22 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:136: T__81 + { + mT__81(); + + } + break; + case 23 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:142: LPAREN + { + mLPAREN(); + + } + break; + case 24 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:149: RPAREN + { + mRPAREN(); + + } + break; + case 25 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:156: QMARK + { + mQMARK(); + + } + break; + case 26 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:162: COLON + { + mCOLON(); + + } + break; + case 27 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:168: SEMICOLON + { + mSEMICOLON(); + + } + break; + case 28 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:178: PERIOD + { + mPERIOD(); + + } + break; + case 29 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:185: UNDERSCORE + { + mUNDERSCORE(); + + } + break; + case 30 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:196: COMMA + { + mCOMMA(); + + } + break; + case 31 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:202: QUOTE + { + mQUOTE(); + + } + break; + case 32 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:208: MODULE + { + mMODULE(); + + } + break; + case 33 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:215: NAME + { + mNAME(); + + } + break; + case 34 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:220: INPUT + { + mINPUT(); + + } + break; + case 35 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:226: OUTPUT + { + mOUTPUT(); + + } + break; + case 36 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:233: INTERNAL + { + mINTERNAL(); + + } + break; + case 37 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:242: MARKING + { + mMARKING(); + + } + break; + case 38 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:250: STATE_VECTOR + { + mSTATE_VECTOR(); + + } + break; + case 39 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:263: TRANSITION + { + mTRANSITION(); + + } + break; + case 40 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:274: LABEL + { + mLABEL(); + + } + break; + case 41 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:280: PRESET + { + mPRESET(); + + } + break; + case 42 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:287: POSTSET + { + mPOSTSET(); + + } + break; + case 43 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:295: TRUE + { + mTRUE(); + + } + break; + case 44 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:300: FALSE + { + mFALSE(); + + } + break; + case 45 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:306: PLUS + { + mPLUS(); + + } + break; + case 46 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:311: MINUS + { + mMINUS(); + + } + break; + case 47 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:317: TIMES + { + mTIMES(); + + } + break; + case 48 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:323: DIV + { + mDIV(); + + } + break; + case 49 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:327: MOD + { + mMOD(); + + } + break; + case 50 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:331: EQUALS + { + mEQUALS(); + + } + break; + case 51 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:338: GREATER + { + mGREATER(); + + } + break; + case 52 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:346: LESS + { + mLESS(); + + } + break; + case 53 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:351: GREATER_EQUAL + { + mGREATER_EQUAL(); + + } + break; + case 54 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:365: LESS_EQUAL + { + mLESS_EQUAL(); + + } + break; + case 55 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:376: EQUIV + { + mEQUIV(); + + } + break; + case 56 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:382: NOT_EQUIV + { + mNOT_EQUIV(); + + } + break; + case 57 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:392: NEGATION + { + mNEGATION(); + + } + break; + case 58 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:401: AND + { + mAND(); + + } + break; + case 59 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:405: OR + { + mOR(); + + } + break; + case 60 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:408: IMPLICATION + { + mIMPLICATION(); + + } + break; + case 61 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:420: BITWISE_NEGATION + { + mBITWISE_NEGATION(); + + } + break; + case 62 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:437: BITWISE_AND + { + mBITWISE_AND(); + + } + break; + case 63 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:449: BITWISE_OR + { + mBITWISE_OR(); + + } + break; + case 64 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:460: BITWISE_XOR + { + mBITWISE_XOR(); + + } + break; + case 65 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:472: BITWISE_LSHIFT + { + mBITWISE_LSHIFT(); + + } + break; + case 66 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:487: BITWISE_RSHIFT + { + mBITWISE_RSHIFT(); + + } + break; + case 67 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:502: INT + { + mINT(); + + } + break; + case 68 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:506: ID + { + mID(); + + } + break; + case 69 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:509: PATH + { + mPATH(); + + } + break; + case 70 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:514: MEMBER + { + mMEMBER(); + + } + break; + case 71 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:521: WS + { + mWS(); + + } + break; + case 72 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:524: COMMENT + { + mCOMMENT(); + + } + break; + case 73 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:532: MULTILINECOMMENT + { + mMULTILINECOMMENT(); + + } + break; + case 74 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:549: XMLCOMMENT + { + mXMLCOMMENT(); + + } + break; + case 75 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1:560: IGNORE + { + mIGNORE(); + + } + break; + + } + + } + + + protected DFA8 dfa8 = new DFA8(this); + protected DFA14 dfa14 = new DFA14(this); + static final String DFA8_eotS = + "\6\uffff"; + static final String DFA8_eofS = + "\6\uffff"; + static final String DFA8_minS = + "\1\60\1\56\1\60\1\56\2\uffff"; + static final String DFA8_maxS = + "\4\172\2\uffff"; + static final String DFA8_acceptS = + "\4\uffff\1\2\1\1"; + static final String DFA8_specialS = + "\6\uffff}>"; + static final String[] DFA8_transitionS = { + "\12\1\7\uffff\32\1\6\uffff\32\1", + "\1\4\1\5\12\3\7\uffff\32\3\1\uffff\1\5\2\uffff\1\2\1\uffff"+ + "\32\3", + "\12\3\7\uffff\32\3\6\uffff\32\3", + "\1\4\1\5\12\3\7\uffff\32\3\1\uffff\1\5\2\uffff\1\2\1\uffff"+ + "\32\3", + "", + "" + }; + + static final short[] DFA8_eot = DFA.unpackEncodedString(DFA8_eotS); + static final short[] DFA8_eof = DFA.unpackEncodedString(DFA8_eofS); + static final char[] DFA8_min = DFA.unpackEncodedStringToUnsignedChars(DFA8_minS); + static final char[] DFA8_max = DFA.unpackEncodedStringToUnsignedChars(DFA8_maxS); + static final short[] DFA8_accept = DFA.unpackEncodedString(DFA8_acceptS); + static final short[] DFA8_special = DFA.unpackEncodedString(DFA8_specialS); + static final short[][] DFA8_transition; + + static { + int numStates = DFA8_transitionS.length; + DFA8_transition = new short[numStates][]; + for (int i=0; i"; + static final String[] DFA14_transitionS = { + "\2\52\1\uffff\2\52\22\uffff\1\52\1\43\1\24\2\uffff\1\37\1\44"+ + "\1\uffff\1\14\1\15\1\36\1\34\1\23\1\35\1\21\1\2\12\50\1\17\1"+ + "\20\1\42\1\40\1\41\1\16\1\uffff\32\51\1\7\1\uffff\1\10\1\47"+ + "\1\22\1\uffff\1\6\1\51\1\5\1\13\1\51\1\33\2\51\1\1\2\51\1\32"+ + "\1\3\1\25\1\26\1\4\2\51\1\30\1\31\1\51\1\27\4\51\1\11\1\45\1"+ + "\12\1\46", + "\1\60\1\57\12\56\1\57\6\uffff\32\56\1\uffff\1\57\2\uffff\1"+ + "\55\1\uffff\15\56\1\53\14\56", + "\1\70\4\uffff\1\67\12\57\7\uffff\32\57\6\uffff\2\57\1\64\5"+ + "\57\1\61\3\57\1\62\2\57\1\63\3\57\1\66\1\57\1\65\4\57", + "\1\60\1\57\12\56\1\57\6\uffff\32\56\1\uffff\1\57\2\uffff\1"+ + "\55\1\uffff\1\72\15\56\1\73\13\56", + "\1\60\1\57\12\56\1\57\6\uffff\32\56\1\uffff\1\57\2\uffff\1"+ + "\55\1\uffff\16\56\1\75\2\56\1\74\10\56", + "\1\60\1\57\12\56\1\57\6\uffff\32\56\1\uffff\1\57\2\uffff\1"+ + "\55\1\uffff\13\56\1\76\2\56\1\77\13\56", + "\1\60\1\57\12\56\1\57\6\uffff\32\56\1\uffff\1\57\2\uffff\1"+ + "\55\1\uffff\21\56\1\100\1\101\7\56", + "", + "", + "", + "", + "\1\60\1\57\12\56\1\57\6\uffff\32\56\1\uffff\1\57\2\uffff\1"+ + "\55\1\uffff\4\56\1\102\25\56", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "\1\60\1\57\12\56\1\57\6\uffff\32\56\1\uffff\1\57\2\uffff\1"+ + "\55\1\uffff\1\103\31\56", + "\1\60\1\57\12\56\1\57\6\uffff\32\56\1\uffff\1\57\2\uffff\1"+ + "\55\1\uffff\24\56\1\104\5\56", + "\1\60\1\57\12\56\1\57\6\uffff\32\56\1\uffff\1\57\2\uffff\1"+ + "\55\1\uffff\1\105\31\56", + "\1\60\1\57\12\56\1\57\6\uffff\32\56\1\uffff\1\57\2\uffff\1"+ + "\55\1\uffff\23\56\1\106\6\56", + "\1\60\1\57\12\56\1\57\6\uffff\32\56\1\uffff\1\57\2\uffff\1"+ + "\55\1\uffff\21\56\1\107\10\56", + "\1\60\1\57\12\56\1\57\6\uffff\32\56\1\uffff\1\57\2\uffff\1"+ + "\55\1\uffff\1\110\31\56", + "\1\60\1\57\12\56\1\57\6\uffff\32\56\1\uffff\1\57\2\uffff\1"+ + "\55\1\uffff\1\111\31\56", + "", + "\12\114\4\uffff\1\112", + "", + "", + "\1\115", + "\1\117\1\120", + "\1\124\32\uffff\1\123\1\122\1\uffff\1\125", + "\1\127", + "\1\131", + "\1\133", + "", + "", + "\2\57\12\135\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff"+ + "\32\57", + "\1\60\1\57\12\56\1\57\6\uffff\32\56\1\uffff\1\57\2\uffff\1"+ + "\55\1\uffff\32\56", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\2\56\1\136\2\56\1\137\11\56\1\140\12\56", + "", + "\12\56\7\uffff\32\56\6\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "", + "\32\142\6\uffff\13\142\1\141\16\142", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\15\57"+ + "\1\143\14\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\1\145"+ + "\15\57\1\144\13\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\21\57"+ + "\1\146\10\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\13\57"+ + "\1\147\2\57\1\150\13\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\1\151"+ + "\31\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\21\57"+ + "\1\152\10\57", + "", + "", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\10\56\1\153\10\56\1\154\10\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\3\56\1\155\26\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\4\56\1\157\11\56\1\156\13\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\22\56\1\160\7\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\1\161\31\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\15\56\1\162\14\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\6\56\1\163\23\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\22\56\1\164\7\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\13\56\1\165\16\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\14\56\1\166\15\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\23\56\1\167\6\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\21\56\1\170\10\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\1\171\31\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\1\172\23\56\1\173\5\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\1\56\1\174\30\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\13\56\1\175\16\56", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "\2\57\12\135\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff"+ + "\32\57", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\13\56\1\176\16\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\24\56\1\u0080\5\56", + "\1\u0081", + "", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\2\57"+ + "\1\u0082\27\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\3\57"+ + "\1\u0083\26\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\21\57"+ + "\1\u0084\10\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\16\57"+ + "\1\u0085\13\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\1\u0086"+ + "\31\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\15\57"+ + "\1\u0087\14\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\21\57"+ + "\1\u0088\10\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\1\u0089"+ + "\31\57", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\15\56\1\u008a\14\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\12\56\1\u008b\17\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\2\56\1\u008d\27\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\22\56\1\u008e\7\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\23\56\1\u008f\6\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\22\56\1\u0090\7\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\3\56\1\u0092\16\56\1\u0091\7\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\4\56\1\u0094\25\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\1\u0095\31\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\4\56\1\u0096\25\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\17\56\1\u0097\12\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\23\56\1\u0099\6\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\15\56\1\u009a\14\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\4\56\1\u009b\25\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\4\56\1\u009c\25\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\22\56\1\u009d\7\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\24\56\1\u009e\5\56", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\23\56\1\u009f\6\56", + "\1\u00a0", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\13\57"+ + "\1\u00a1\16\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\32\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\12\57"+ + "\1\u00a3\17\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\2\57"+ + "\1\u00a4\27\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\22\57"+ + "\1\u00a5\7\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\22\57"+ + "\1\u00a6\7\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\32\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\15\57"+ + "\1\u00a8\14\57", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\10\56\1\u00aa\21\56", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\4\56\1\u00ab\25\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\4\56\1\u00ac\25\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\22\56\1\u00ad\7\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\22\56\1\u00ae\7\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\23\56\1\u00af\6\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\10\56\1\u00b0\21\56", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\21\56\1\u00b1\10\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\30\56\1\u00b2\1\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\24\56\1\u00b4\5\56", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\4\56\1\u00b5\25\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\22\56\1\u00b6\7\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\13\56\1\u00b8\16\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\4\56\1\u00b9\25\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\3\56\1\u00ba\26\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\12\142\7\uffff\32\142\4\uffff\1\142\1\uffff\32\142", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\24\57"+ + "\1\u00bc\5\57", + "", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\10\57"+ + "\1\u00bd\21\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\4\57"+ + "\1\u00be\25\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\22\57"+ + "\1\u00bf\7\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\23\57"+ + "\1\u00c0\6\57", + "", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\22\57"+ + "\1\u00c1\7\57", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\15\56\1\u00c2\14\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\22\56\1\u00c3\7\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\23\56\1\u00c4\6\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\4\56\1\u00c5\25\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\23\56\1\u00c8\6\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\23\56\1\u00c9\6\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\23\56\1\u00cb\6\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\25\56\1\u00cc\4\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\10\56\1\u00cd\21\56", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\4\56\1\u00d0\25\56", + "", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\3\57"+ + "\1\u00d1\26\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\15\57"+ + "\1\u00d2\14\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\22\57"+ + "\1\u00d3\7\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\32\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\32\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\10\57"+ + "\1\u00d6\21\57", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\6\56\1\u00d7\23\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\22\56\1\u00d8\7\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\23\56\1\u00da\6\56", + "", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\10\56\1\u00db\21\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\4\56\1\u00de\25\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\23\56\1\u00df\6\56", + "", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\4\57"+ + "\1\u00e1\25\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\6\57"+ + "\1\u00e2\23\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\22\57"+ + "\1\u00e3\7\57", + "", + "", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\23\57"+ + "\1\u00e4\6\57", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\16\56\1\u00e8\13\56", + "", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\2\56\1\u00e9\27\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\10\56\1\u00ea\21\56", + "", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\32\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\32\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\32\57", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\10\57"+ + "\1\u00ee\21\57", + "", + "", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\15\56\1\u00ef\14\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\23\56\1\u00f0\6\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\16\56\1\u00f1\13\56", + "", + "", + "", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\16\57"+ + "\1\u00f2\13\57", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\16\56\1\u00f4\13\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\15\56\1\u00f5\14\56", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\15\57"+ + "\1\u00f6\14\57", + "", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\21\56\1\u00f7\10\56", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "\14\57\7\uffff\32\57\1\uffff\1\57\2\uffff\1\57\1\uffff\32\57", + "\1\60\1\57\12\56\7\uffff\32\56\1\uffff\1\57\2\uffff\1\55\1"+ + "\uffff\32\56", + "", + "", + "" + }; + + static final short[] DFA14_eot = DFA.unpackEncodedString(DFA14_eotS); + static final short[] DFA14_eof = DFA.unpackEncodedString(DFA14_eofS); + static final char[] DFA14_min = DFA.unpackEncodedStringToUnsignedChars(DFA14_minS); + static final char[] DFA14_max = DFA.unpackEncodedStringToUnsignedChars(DFA14_maxS); + static final short[] DFA14_accept = DFA.unpackEncodedString(DFA14_acceptS); + static final short[] DFA14_special = DFA.unpackEncodedString(DFA14_specialS); + static final short[][] DFA14_transition; + + static { + int numStates = DFA14_transitionS.length; + DFA14_transition = new short[numStates][]; + for (int i=0; i + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +// $ANTLR 3.3 Nov 30, 2010 12:50:56 /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g 2011-09-05 15:36:30 + + package edu.utah.ece.async.lema.verification.platu.platuLpn.io; + + import java.util.StringTokenizer; +import java.io.File; +import java.util.Map.Entry; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Queue; + +import org.antlr.runtime.*; + +import edu.utah.ece.async.lema.verification.platu.expression.*; +import edu.utah.ece.async.lema.verification.platu.platuLpn.*; +import edu.utah.ece.async.lema.verification.platu.platuLpn.io.Instance; +import edu.utah.ece.async.lema.verification.platu.project.Project; + +import java.util.List; +import java.util.ArrayList; + +public class PlatuInstParser extends Parser { + public static final String[] tokenNames = new String[] { + "", "", "", "", "PATH", "ID", "INT", "MEMBER", "LPAREN", "RPAREN", "TRUE", "FALSE", "QMARK", "COLON", "SEMICOLON", "PERIOD", "UNDERSCORE", "COMMA", "QUOTE", "MODULE", "NAME", "INPUT", "OUTPUT", "INTERNAL", "MARKING", "STATE_VECTOR", "TRANSITION", "LABEL", "PRESET", "POSTSET", "PLUS", "MINUS", "TIMES", "DIV", "MOD", "EQUALS", "GREATER", "LESS", "GREATER_EQUAL", "LESS_EQUAL", "EQUIV", "NOT_EQUIV", "NEGATION", "AND", "OR", "IMPLICATION", "BITWISE_NEGATION", "BITWISE_AND", "BITWISE_OR", "BITWISE_XOR", "BITWISE_LSHIFT", "BITWISE_RSHIFT", "LETTER", "DIGIT", "FILE", "WS", "COMMENT", "MULTILINECOMMENT", "XMLCOMMENT", "IGNORE", "'include'", "'/include'", "'main'", "'/mod'", "'process'", "'/process'", "'class'", "'arg'", "'['", "']'", "'/class'", "'const'", "'/const'", "'/var'", "'{'", "'}'", "'/marking'", "'/transition'", "'assert'", "'condition'", "'delay'", "'inf'" + }; + public static final int EOF=-1; + public static final int T__60=60; + public static final int T__61=61; + public static final int T__62=62; + public static final int T__63=63; + public static final int T__64=64; + public static final int T__65=65; + public static final int T__66=66; + public static final int T__67=67; + public static final int T__68=68; + public static final int T__69=69; + public static final int T__70=70; + public static final int T__71=71; + public static final int T__72=72; + public static final int T__73=73; + public static final int T__74=74; + public static final int T__75=75; + public static final int T__76=76; + public static final int T__77=77; + public static final int T__78=78; + public static final int T__79=79; + public static final int T__80=80; + public static final int T__81=81; + public static final int PATH=4; + public static final int ID=5; + public static final int INT=6; + public static final int MEMBER=7; + public static final int LPAREN=8; + public static final int RPAREN=9; + public static final int TRUE=10; + public static final int FALSE=11; + public static final int QMARK=12; + public static final int COLON=13; + public static final int SEMICOLON=14; + public static final int PERIOD=15; + public static final int UNDERSCORE=16; + public static final int COMMA=17; + public static final int QUOTE=18; + public static final int MODULE=19; + public static final int NAME=20; + public static final int INPUT=21; + public static final int OUTPUT=22; + public static final int INTERNAL=23; + public static final int MARKING=24; + public static final int STATE_VECTOR=25; + public static final int TRANSITION=26; + public static final int LABEL=27; + public static final int PRESET=28; + public static final int POSTSET=29; + public static final int PLUS=30; + public static final int MINUS=31; + public static final int TIMES=32; + public static final int DIV=33; + public static final int MOD=34; + public static final int EQUALS=35; + public static final int GREATER=36; + public static final int LESS=37; + public static final int GREATER_EQUAL=38; + public static final int LESS_EQUAL=39; + public static final int EQUIV=40; + public static final int NOT_EQUIV=41; + public static final int NEGATION=42; + public static final int AND=43; + public static final int OR=44; + public static final int IMPLICATION=45; + public static final int BITWISE_NEGATION=46; + public static final int BITWISE_AND=47; + public static final int BITWISE_OR=48; + public static final int BITWISE_XOR=49; + public static final int BITWISE_LSHIFT=50; + public static final int BITWISE_RSHIFT=51; + public static final int LETTER=52; + public static final int DIGIT=53; + public static final int FILE=54; + public static final int WS=55; + public static final int COMMENT=56; + public static final int MULTILINECOMMENT=57; + public static final int XMLCOMMENT=58; + public static final int IGNORE=59; + + // delegates + // delegators + + + public PlatuInstParser(TokenStream input) { + this(input, new RecognizerSharedState()); + } + public PlatuInstParser(TokenStream input, RecognizerSharedState state) { + super(input, state); + + } + + + @Override + public String[] getTokenNames() { return PlatuInstParser.tokenNames; } + @Override + public String getGrammarFileName() { return "/Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g"; } + + + // static variables + static private int INFINITY = Integer.MAX_VALUE; + static private boolean main = false; // true if main module has been parsed + static private ExpressionNode ZERO = new ConstNode("FALSE", 0); // constant false node + static private ExpressionNode ONE = new ConstNode("TRUE", 1); // constant true node + static private Expression TrueExpr = new Expression(ONE); // constant true expression + static public HashMap LpnMap = new HashMap(); // all modules parsed, keyed by module name + static private HashMap GlobalVarHashMap = new HashMap(); // global variables and associated values + static private HashMap GlobalVarNodeMap = new HashMap(); + static public List InstanceList = new ArrayList(); + static public HashSet includeSet = new HashSet(); + + // non-static variables + private HashMap VarNodeMap = new HashMap(); // maps variable name to variable object + private DualHashMap VarIndexMap = new DualHashMap(); // maps variables to an array index + private HashMap GlobalConstHashMap = new HashMap(); // global constants within a single lpn file + private HashMap ConstHashMap = new HashMap(); // constants within a single module + private HashMap StatevectorMap = new HashMap(); // module variables mapped to initial values + private HashMap VarCountMap = new HashMap(); // count of the references to each module variable + private List inputTranList = null; // list of lpn transitions which affect a modules input + private List outputTranList = null; // list of lpn transitions which affect a modules output + private List argumentList = null; // list of class arguments + private VarSet Inputs = null; // module inputs + private VarSet Internals = null; // module internal variables + private VarSet Outputs = null; // module outputs + private int VariableIndex = 0; // count of index assigned to module variables + private int TransitionIndex = 0; // count of index assigned to lpn transitions + private int GlobalCount = 0; // number of global variables defined in this lpn file + private int GlobalSize = 0; // number of global variables defined + + // methods + private static void error(String error){ + System.err.println(error); + System.exit(1); + } + + private void createGlobalArray(String var, List dimensionList){ + int iter = dimensionList.size() - 1; + int dIndex = 0; + int arraySize = dimensionList.get(dIndex++); + int lastSize = 0; + List topLevelArray = new ArrayList(arraySize); + + Queue> arrayQueue = new LinkedList>(); + arrayQueue.offer(topLevelArray); + + while(iter > 0){ + lastSize = arraySize; + arraySize = dimensionList.get(dIndex++); + int qSize = arrayQueue.size(); + for(int i = 0; i < qSize; i++){ + List array = arrayQueue.poll(); + for(int j = 0 ; j < lastSize; j++){ + List newArray = new ArrayList(arraySize); + array.add(j, newArray); + arrayQueue.offer(newArray); + } + } + + iter--; + } + + int varCount = 0; + dIndex--; + arraySize = dimensionList.get(dIndex); + + List varList = new ArrayList(); + while(!arrayQueue.isEmpty()){ + List array = arrayQueue.poll(); + for(int i = 0; i < arraySize; i++){ + String name = var + "." + varCount; + varCount++; + + int index = VariableIndex++; + VarNode element = new VarNode(name, index); + element.setType(VarType.GLOBAL); + array.add(i, element); + varList.add(element); + + // add variable and value to state vector + StatevectorMap.put(name, 0); + + // generate variable index and create new var node + VarIndexMap.insert(name, index); + VarNodeMap.put(name, element); + } + } + + ArrayNode newArray = new ArrayNode(var, topLevelArray, dimensionList.size(), dimensionList, varList); + newArray.setType(VarType.GLOBAL); + VarNodeMap.put(var, newArray); + // VarCountMap.put(var, 0); + // Inputs.add(var); + Outputs.add(var); + } + + private void createInputArray(String var, List dimensionList){ + int iter = dimensionList.size() - 1; + int dIndex = 0; + int arraySize = dimensionList.get(dIndex++); + int lastSize = 0; + List topLevelArray = new ArrayList(arraySize); + + Queue> arrayQueue = new LinkedList>(); + arrayQueue.offer(topLevelArray); + + while(iter > 0){ + lastSize = arraySize; + arraySize = dimensionList.get(dIndex++); + int qSize = arrayQueue.size(); + for(int i = 0; i < qSize; i++){ + List array = arrayQueue.poll(); + for(int j = 0 ; j < lastSize; j++){ + List newArray = new ArrayList(arraySize); + array.add(j, newArray); + arrayQueue.offer(newArray); + } + } + + iter--; + } + + int varCount = 0; + dIndex--; + arraySize = dimensionList.get(dIndex); + + List varList = new ArrayList(); + while(!arrayQueue.isEmpty()){ + List array = arrayQueue.poll(); + for(int i = 0; i < arraySize; i++){ + String name = var + "." + varCount; + varCount++; + + int index = VariableIndex++; + VarNode element = new VarNode(name, index); + element.setType(VarType.INPUT); + array.add(i, element); + varList.add(element); + + // add variable and value to state vector + StatevectorMap.put(name, 0); + + // generate variable index and create new var node + VarIndexMap.insert(name, index); + VarNodeMap.put(name, element); + } + } + + ArrayNode newArray = new ArrayNode(var, topLevelArray, dimensionList.size(), dimensionList, varList); + newArray.setType(VarType.INPUT); + VarNodeMap.put(var, newArray); + // VarCountMap.put(var, 0); + Inputs.add(var); + argumentList.add(var); + } + + + + // $ANTLR start "parseLpnFile" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:201:1: parseLpnFile[Project prj] : ( include )? ( globalConstants )? ( globalVariables )? ( main[prj] )? ( moduleClass[prj] )* EOF ; + public final void parseLpnFile(Project prj) { + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:202:5: ( ( include )? ( globalConstants )? ( globalVariables )? ( main[prj] )? ( moduleClass[prj] )* EOF ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:202:7: ( include )? ( globalConstants )? ( globalVariables )? ( main[prj] )? ( moduleClass[prj] )* EOF + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:202:7: ( include )? + int alt1=2; + int LA1_0 = input.LA(1); + + if ( (LA1_0==LESS) ) { + int LA1_1 = input.LA(2); + + if ( (LA1_1==60) ) { + alt1=1; + } + } + switch (alt1) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:202:7: include + { + pushFollow(FOLLOW_include_in_parseLpnFile52); + include(); + + state._fsp--; + + + } + break; + + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:202:16: ( globalConstants )? + int alt2=2; + int LA2_0 = input.LA(1); + + if ( (LA2_0==LESS) ) { + int LA2_1 = input.LA(2); + + if ( (LA2_1==71) ) { + alt2=1; + } + } + switch (alt2) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:202:16: globalConstants + { + pushFollow(FOLLOW_globalConstants_in_parseLpnFile55); + globalConstants(); + + state._fsp--; + + + } + break; + + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:202:33: ( globalVariables )? + int alt3=2; + int LA3_0 = input.LA(1); + + if ( (LA3_0==LESS) ) { + int LA3_1 = input.LA(2); + + if ( (LA3_1==INTERNAL) ) { + alt3=1; + } + } + switch (alt3) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:202:33: globalVariables + { + pushFollow(FOLLOW_globalVariables_in_parseLpnFile58); + globalVariables(); + + state._fsp--; + + + } + break; + + } + + + // check that global constants are consistently defined in each lpn file + if(GlobalSize > 0 && GlobalCount != GlobalSize){ + System.err.println("error: global variable definitions are inconsistent"); + System.exit(1); + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:210:8: ( main[prj] )? + int alt4=2; + int LA4_0 = input.LA(1); + + if ( (LA4_0==LESS) ) { + int LA4_1 = input.LA(2); + + if ( (LA4_1==MODULE) ) { + alt4=1; + } + } + switch (alt4) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:210:8: main[prj] + { + pushFollow(FOLLOW_main_in_parseLpnFile82); + main(); + + state._fsp--; + + + } + break; + + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:210:19: ( moduleClass[prj] )* + loop5: + do { + int alt5=2; + int LA5_0 = input.LA(1); + + if ( (LA5_0==LESS) ) { + alt5=1; + } + + + switch (alt5) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:210:20: moduleClass[prj] + { + pushFollow(FOLLOW_moduleClass_in_parseLpnFile87); + moduleClass(prj); + + state._fsp--; + + + } + break; + + default : + break loop5; + } + } while (true); + + match(input,EOF,FOLLOW_EOF_in_parseLpnFile92); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return ; + } + // $ANTLR end "parseLpnFile" + + + // $ANTLR start "include" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:213:1: include : '<' 'include' '>' ( PATH ';' )+ '<' '/include' '>' ; + public final void include() { + Token PATH1=null; + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:214:2: ( '<' 'include' '>' ( PATH ';' )+ '<' '/include' '>' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:214:4: '<' 'include' '>' ( PATH ';' )+ '<' '/include' '>' + { + match(input,LESS,FOLLOW_LESS_in_include110); + match(input,60,FOLLOW_60_in_include112); + match(input,GREATER,FOLLOW_GREATER_in_include114); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:214:22: ( PATH ';' )+ + int cnt6=0; + loop6: + do { + int alt6=2; + int LA6_0 = input.LA(1); + + if ( (LA6_0==PATH) ) { + alt6=1; + } + + + switch (alt6) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:214:23: PATH ';' + { + PATH1=(Token)match(input,PATH,FOLLOW_PATH_in_include117); + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_include119); + + File f = new File((PATH1!=null?PATH1.getText():null)); + includeSet.add(f.getAbsolutePath()); + + + } + break; + + default : + if ( cnt6 >= 1 ) break loop6; + EarlyExitException eee = + new EarlyExitException(6, input); + throw eee; + } + cnt6++; + } while (true); + + match(input,LESS,FOLLOW_LESS_in_include131); + match(input,61,FOLLOW_61_in_include133); + match(input,GREATER,FOLLOW_GREATER_in_include135); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return ; + } + // $ANTLR end "include" + + + // $ANTLR start "main" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:222:1: main[Project prj] : '<' 'mod' 'name' '=' '\"' 'main' '\"' '>' ( variables )? ( constants )? instantiation '<' '/mod' '>' ; + public final void main() { + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:223:2: ( '<' 'mod' 'name' '=' '\"' 'main' '\"' '>' ( variables )? ( constants )? instantiation '<' '/mod' '>' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:223:4: '<' 'mod' 'name' '=' '\"' 'main' '\"' '>' ( variables )? ( constants )? instantiation '<' '/mod' '>' + { + match(input,LESS,FOLLOW_LESS_in_main148); + match(input,MODULE,FOLLOW_MODULE_in_main150); + match(input,NAME,FOLLOW_NAME_in_main152); + match(input,EQUALS,FOLLOW_EQUALS_in_main154); + match(input,QUOTE,FOLLOW_QUOTE_in_main156); + match(input,62,FOLLOW_62_in_main158); + match(input,QUOTE,FOLLOW_QUOTE_in_main160); + match(input,GREATER,FOLLOW_GREATER_in_main162); + + if(main == true){ + System.err.println("error: multiple main modules"); + System.exit(1); + } + + main = true; + + // initialize non static variables for new module + VarIndexMap = new DualHashMap(); + ConstHashMap = new HashMap(); + VarNodeMap = new HashMap(); + VarCountMap = new HashMap(); + Inputs = new VarSet(); + Internals = new VarSet(); + Outputs = new VarSet(); + inputTranList = new LinkedList(); + outputTranList = new LinkedList(); + argumentList = new ArrayList(); + StatevectorMap = new HashMap(); + VariableIndex = 0; + + // add global variables to initial state vector and label as an input & output + for(Entry e : GlobalVarHashMap.entrySet()){ + String globalVar = e.getKey(); + if(GlobalVarNodeMap.containsKey(globalVar)) continue; + + StatevectorMap.put(globalVar, e.getValue()); + int index = VariableIndex++; + VarIndexMap.insert(globalVar, index); + + VarNode globalVarNode = new VarNode(globalVar, index); + globalVarNode.setType(VarType.GLOBAL); + VarNodeMap.put(globalVar, globalVarNode); + // Inputs.add(globalVar); + Outputs.add(globalVar); + } + + // add global arrays + for(VarNode node : GlobalVarNodeMap.values()){ + ArrayNode arrayNode = (ArrayNode) node; + + // construct array + createGlobalArray(arrayNode.getName(), arrayNode.getDimensionList()); + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:270:3: ( variables )? + int alt7=2; + int LA7_0 = input.LA(1); + + if ( (LA7_0==LESS) ) { + int LA7_1 = input.LA(2); + + if ( (LA7_1==INTERNAL) ) { + alt7=1; + } + } + switch (alt7) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:270:3: variables + { + pushFollow(FOLLOW_variables_in_main171); + variables(); + + state._fsp--; + + + } + break; + + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:270:14: ( constants )? + int alt8=2; + int LA8_0 = input.LA(1); + + if ( (LA8_0==LESS) ) { + alt8=1; + } + switch (alt8) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:270:14: constants + { + pushFollow(FOLLOW_constants_in_main174); + constants(); + + state._fsp--; + + + } + break; + + } + + pushFollow(FOLLOW_instantiation_in_main177); + instantiation(); + + state._fsp--; + + match(input,LESS,FOLLOW_LESS_in_main179); + match(input,63,FOLLOW_63_in_main181); + match(input,GREATER,FOLLOW_GREATER_in_main183); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return ; + } + // $ANTLR end "main" + + + // $ANTLR start "process" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:273:1: process : '<' 'process' 'name' '=' '\"' processName= ID '\"' '>' '<' '/process' '>' ; + public final void process() { + //Token processName=null; + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:274:2: ( '<' 'process' 'name' '=' '\"' processName= ID '\"' '>' '<' '/process' '>' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:274:4: '<' 'process' 'name' '=' '\"' processName= ID '\"' '>' '<' '/process' '>' + { + match(input,LESS,FOLLOW_LESS_in_process198); + match(input,64,FOLLOW_64_in_process200); + match(input,NAME,FOLLOW_NAME_in_process202); + match(input,EQUALS,FOLLOW_EQUALS_in_process204); + match(input,QUOTE,FOLLOW_QUOTE_in_process206); + //processName=(Token) + match(input,ID,FOLLOW_ID_in_process210); + match(input,QUOTE,FOLLOW_QUOTE_in_process212); + match(input,GREATER,FOLLOW_GREATER_in_process214); + match(input,LESS,FOLLOW_LESS_in_process216); + match(input,65,FOLLOW_65_in_process218); + match(input,GREATER,FOLLOW_GREATER_in_process220); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return ; + } + // $ANTLR end "process" + + + // $ANTLR start "moduleClass" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:278:1: moduleClass[Project prj] returns [LPN lpn] : ( '<' 'class' 'name' '=' '\"' modName= ID '\"' 'arg' '=' '\"' ( ( (arrayArg2= ID ( '[' arrayExpr2= expression ']' )+ ) | (arg2= ID ) ) ( ( ',' arrayArg= ID ( '[' arrayExpr= expression ']' )+ ) | ( ',' arg= ID ) )* )? '\"' '>' ( constants )? variables logic '<' '/class' '>' ) ; + public final PlatuLPN moduleClass(Project prj) { + PlatuLPN lpn = null; + + Token modName=null; + Token arrayArg2=null; + Token arg2=null; + Token arrayArg=null; + Token arg=null; + PlatuInstParser.expression_return arrayExpr2 = null; + + PlatuInstParser.expression_return arrayExpr = null; + + PlatuInstParser.logic_return logic2 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:279:5: ( ( '<' 'class' 'name' '=' '\"' modName= ID '\"' 'arg' '=' '\"' ( ( (arrayArg2= ID ( '[' arrayExpr2= expression ']' )+ ) | (arg2= ID ) ) ( ( ',' arrayArg= ID ( '[' arrayExpr= expression ']' )+ ) | ( ',' arg= ID ) )* )? '\"' '>' ( constants )? variables logic '<' '/class' '>' ) ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:279:7: ( '<' 'class' 'name' '=' '\"' modName= ID '\"' 'arg' '=' '\"' ( ( (arrayArg2= ID ( '[' arrayExpr2= expression ']' )+ ) | (arg2= ID ) ) ( ( ',' arrayArg= ID ( '[' arrayExpr= expression ']' )+ ) | ( ',' arg= ID ) )* )? '\"' '>' ( constants )? variables logic '<' '/class' '>' ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:279:7: ( '<' 'class' 'name' '=' '\"' modName= ID '\"' 'arg' '=' '\"' ( ( (arrayArg2= ID ( '[' arrayExpr2= expression ']' )+ ) | (arg2= ID ) ) ( ( ',' arrayArg= ID ( '[' arrayExpr= expression ']' )+ ) | ( ',' arg= ID ) )* )? '\"' '>' ( constants )? variables logic '<' '/class' '>' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:279:9: '<' 'class' 'name' '=' '\"' modName= ID '\"' 'arg' '=' '\"' ( ( (arrayArg2= ID ( '[' arrayExpr2= expression ']' )+ ) | (arg2= ID ) ) ( ( ',' arrayArg= ID ( '[' arrayExpr= expression ']' )+ ) | ( ',' arg= ID ) )* )? '\"' '>' ( constants )? variables logic '<' '/class' '>' + { + match(input,LESS,FOLLOW_LESS_in_moduleClass243); + match(input,66,FOLLOW_66_in_moduleClass245); + match(input,NAME,FOLLOW_NAME_in_moduleClass247); + match(input,EQUALS,FOLLOW_EQUALS_in_moduleClass249); + match(input,QUOTE,FOLLOW_QUOTE_in_moduleClass251); + modName=(Token)match(input,ID,FOLLOW_ID_in_moduleClass255); + + // module names must be unique + if(LpnMap.containsKey((modName!=null?modName.getText():null))){ + System.err.println("error on line " + (modName!=null?modName.getLine():null) + ": module " + (modName!=null?modName.getText():null) + " already exists"); + System.exit(1); + } + + if(modName!=null && modName.getText().equals("main")){ + error("error on line " + modName.getLine() + ": main is reserved"); + } + + // initialize non static variables for new module + VarIndexMap = new DualHashMap(); + ConstHashMap = new HashMap(); + VarNodeMap = new HashMap(); + VarCountMap = new HashMap(); + Inputs = new VarSet(); + Internals = new VarSet(); + Outputs = new VarSet(); + inputTranList = new LinkedList(); + outputTranList = new LinkedList(); + argumentList = new ArrayList(); + StatevectorMap = new HashMap(); + VariableIndex = 0; + + // add global variables to initial state vector and label as an input & output + for(Entry e : GlobalVarHashMap.entrySet()){ + String globalVar = e.getKey(); + if(GlobalVarNodeMap.containsKey(globalVar)) continue; + + StatevectorMap.put(globalVar, e.getValue()); + int index = VariableIndex++; + VarIndexMap.insert(globalVar, index); + + VarNode globalVarNode = new VarNode(globalVar, index); + globalVarNode.setType(VarType.GLOBAL); + VarNodeMap.put(globalVar, globalVarNode); + // Inputs.add(globalVar); + Outputs.add(globalVar); + } + + // add global arrays + for(VarNode node : GlobalVarNodeMap.values()){ + ArrayNode arrayNode = (ArrayNode) node; + + // construct array + createGlobalArray(arrayNode.getName(), arrayNode.getDimensionList()); + } + + match(input,QUOTE,FOLLOW_QUOTE_in_moduleClass270); + match(input,67,FOLLOW_67_in_moduleClass272); + match(input,EQUALS,FOLLOW_EQUALS_in_moduleClass274); + match(input,QUOTE,FOLLOW_QUOTE_in_moduleClass276); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:329:24: ( ( (arrayArg2= ID ( '[' arrayExpr2= expression ']' )+ ) | (arg2= ID ) ) ( ( ',' arrayArg= ID ( '[' arrayExpr= expression ']' )+ ) | ( ',' arg= ID ) )* )? + int alt13=2; + int LA13_0 = input.LA(1); + + if ( (LA13_0==ID) ) { + alt13=1; + } + switch (alt13) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:329:25: ( (arrayArg2= ID ( '[' arrayExpr2= expression ']' )+ ) | (arg2= ID ) ) ( ( ',' arrayArg= ID ( '[' arrayExpr= expression ']' )+ ) | ( ',' arg= ID ) )* + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:329:25: ( (arrayArg2= ID ( '[' arrayExpr2= expression ']' )+ ) | (arg2= ID ) ) + int alt10=2; + int LA10_0 = input.LA(1); + + if ( (LA10_0==ID) ) { + int LA10_1 = input.LA(2); + + if ( (LA10_1==68) ) { + alt10=1; + } + else if ( ((LA10_1>=COMMA && LA10_1<=QUOTE)) ) { + alt10=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 10, 1, input); + + throw nvae; + } + } + else { + NoViableAltException nvae = + new NoViableAltException("", 10, 0, input); + + throw nvae; + } + switch (alt10) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:329:26: (arrayArg2= ID ( '[' arrayExpr2= expression ']' )+ ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:329:26: (arrayArg2= ID ( '[' arrayExpr2= expression ']' )+ ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:329:27: arrayArg2= ID ( '[' arrayExpr2= expression ']' )+ + { + arrayArg2=(Token)match(input,ID,FOLLOW_ID_in_moduleClass283); + + // check aginst globals and other inputs + if(GlobalConstHashMap.containsKey((arrayArg2!=null?arrayArg2.getText():null))){ + System.err.println("error on line " + (arrayArg2!=null?arrayArg2.getLine():null) + ": variable " + (arrayArg2!=null?arrayArg2.getText():null) + " is already defined as a global constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey((arrayArg2!=null?arrayArg2.getText():null))){ + System.err.println("error on line " + (arrayArg2!=null?arrayArg2.getLine():null) + ": variable " + (arrayArg2!=null?arrayArg2.getText():null) + " is already defined as a global variable"); + System.exit(1); + } + else if(VarNodeMap.containsKey((arrayArg2!=null?arrayArg2.getText():null))){ + System.err.println("error on line " + (arrayArg2!=null?arrayArg2.getLine():null) + ": variable " + (arrayArg2!=null?arrayArg2.getText():null) + " is already defined"); + System.exit(1); + } + + List dimensionList = new ArrayList(); + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:347:6: ( '[' arrayExpr2= expression ']' )+ + int cnt9=0; + loop9: + do { + int alt9=2; + int LA9_0 = input.LA(1); + + if ( (LA9_0==68) ) { + alt9=1; + } + + + switch (alt9) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:347:7: '[' arrayExpr2= expression ']' + { + match(input,68,FOLLOW_68_in_moduleClass300); + pushFollow(FOLLOW_expression_in_moduleClass304); + arrayExpr2=expression(); + + state._fsp--; + + + dimensionList.add((arrayExpr2!=null?arrayExpr2.value:0)); + + match(input,69,FOLLOW_69_in_moduleClass320); + + } + break; + + default : + if ( cnt9 >= 1 ) break loop9; + EarlyExitException eee = + new EarlyExitException(9, input); + throw eee; + } + cnt9++; + } while (true); + + + createInputArray((arrayArg2!=null?arrayArg2.getText():null), dimensionList); + + + } + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:355:10: (arg2= ID ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:355:10: (arg2= ID ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:355:11: arg2= ID + { + arg2=(Token)match(input,ID,FOLLOW_ID_in_moduleClass344); + if (arg2==null) { + return null; + } + // check against globals + else if(GlobalConstHashMap.containsKey(arg2.getText())){ + System.err.println("error on line " + arg2.getLine() + ": variable " + arg2.getText() + " is already defined as a global constant"); + return null; + } + else if(GlobalVarHashMap.containsKey(arg2.getText())){ + System.err.println("error on line " + arg2.getLine() + ": variable " + arg2.getText() + " is already defined as a global variable"); + return null; + } + + // add variable and value to state vector + StatevectorMap.put(arg2.getText(), 0); + + // generate variable index and create new var node + int index = VariableIndex++; + VarIndexMap.insert(arg2.getText(), index); + + VarNode inputVarNode = new VarNode(arg2.getText(), index); + inputVarNode.setType(VarType.INPUT); + VarNodeMap.put(arg2.getText(), inputVarNode); + // VarCountMap.put(arg2.getText(), 0); + + argumentList.add(arg2.getText()); + Inputs.add(arg2.getText()); + + + } + + + } + break; + + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:382:9: ( ( ',' arrayArg= ID ( '[' arrayExpr= expression ']' )+ ) | ( ',' arg= ID ) )* + loop12: + do { + int alt12=3; + int LA12_0 = input.LA(1); + + if ( (LA12_0==COMMA) ) { + int LA12_2 = input.LA(2); + + if ( (LA12_2==ID) ) { + int LA12_3 = input.LA(3); + + if ( (LA12_3==68) ) { + alt12=1; + } + else if ( ((LA12_3>=COMMA && LA12_3<=QUOTE)) ) { + alt12=2; + } + + + } + + + } + + + switch (alt12) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:382:10: ( ',' arrayArg= ID ( '[' arrayExpr= expression ']' )+ ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:382:10: ( ',' arrayArg= ID ( '[' arrayExpr= expression ']' )+ ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:382:11: ',' arrayArg= ID ( '[' arrayExpr= expression ']' )+ + { + match(input,COMMA,FOLLOW_COMMA_in_moduleClass364); + arrayArg=(Token)match(input,ID,FOLLOW_ID_in_moduleClass368); + + // check aginst globals and other inputs + if(GlobalConstHashMap.containsKey((arrayArg!=null?arrayArg.getText():null))){ + System.err.println("error on line " + (arrayArg!=null?arrayArg.getLine():null) + ": variable " + (arrayArg!=null?arrayArg.getText():null) + " is already defined as a global constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey((arrayArg!=null?arrayArg.getText():null))){ + System.err.println("error on line " + (arrayArg!=null?arrayArg.getLine():null) + ": variable " + (arrayArg!=null?arrayArg.getText():null) + " is already defined as a global variable"); + System.exit(1); + } + else if(VarNodeMap.containsKey((arrayArg!=null?arrayArg.getText():null))){ + System.err.println("error on line " + (arrayArg!=null?arrayArg.getLine():null) + ": variable " + (arrayArg!=null?arrayArg.getText():null) + " is already defined"); + System.exit(1); + } + + List dimensionList = new ArrayList(); + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:400:6: ( '[' arrayExpr= expression ']' )+ + int cnt11=0; + loop11: + do { + int alt11=2; + int LA11_0 = input.LA(1); + + if ( (LA11_0==68) ) { + alt11=1; + } + + + switch (alt11) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:400:7: '[' arrayExpr= expression ']' + { + match(input,68,FOLLOW_68_in_moduleClass384); + pushFollow(FOLLOW_expression_in_moduleClass388); + arrayExpr=expression(); + + state._fsp--; + + + dimensionList.add((arrayExpr!=null?arrayExpr.value:0)); + + match(input,69,FOLLOW_69_in_moduleClass404); + + } + break; + + default : + if ( cnt11 >= 1 ) break loop11; + EarlyExitException eee = + new EarlyExitException(11, input); + throw eee; + } + cnt11++; + } while (true); + + + createInputArray((arrayArg!=null?arrayArg.getText():null), dimensionList); + + + } + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:408:10: ( ',' arg= ID ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:408:10: ( ',' arg= ID ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:408:11: ',' arg= ID + { + match(input,COMMA,FOLLOW_COMMA_in_moduleClass427); + arg=(Token)match(input,ID,FOLLOW_ID_in_moduleClass431); + if (arg==null) return null; + + // check aginst globals and other inputs + if(GlobalConstHashMap.containsKey(arg.getText())){ + System.err.println("error on line " + arg.getLine() + ": variable " + arg.getText() + " is already defined as a global constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey(arg.getText())){ + System.err.println("error on line " + arg.getLine() + ": variable " + arg.getText() + " is already defined as a global variable"); + System.exit(1); + } + else if(VarNodeMap.containsKey(arg.getText())){ + System.err.println("error on line " + arg.getLine() + ": variable " + arg.getText() + " is already defined"); + System.exit(1); + } + + // add variable and value to state vector + StatevectorMap.put(arg.getText(), 0); + + // generate variable index and create new var node + int index = VariableIndex++; + VarIndexMap.insert(arg.getText(), index); + + VarNode inputVarNode = new VarNode(arg.getText(), index); + inputVarNode.setType(VarType.INPUT); + VarNodeMap.put(arg.getText(), inputVarNode); + // VarCountMap.put(arg.getText(), 0); + + argumentList.add(arg.getText()); + Inputs.add(arg.getText()); + + + } + + + } + break; + + default : + break loop12; + } + } while (true); + + + } + break; + + } + + match(input,QUOTE,FOLLOW_QUOTE_in_moduleClass454); + match(input,GREATER,FOLLOW_GREATER_in_moduleClass456); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:439:21: ( constants )? + int alt14=2; + int LA14_0 = input.LA(1); + + if ( (LA14_0==LESS) ) { + int LA14_1 = input.LA(2); + + if ( (LA14_1==71) ) { + alt14=1; + } + } + switch (alt14) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:439:21: constants + { + pushFollow(FOLLOW_constants_in_moduleClass458); + constants(); + + state._fsp--; + + + } + break; + + } + + pushFollow(FOLLOW_variables_in_moduleClass461); + variables(); + + state._fsp--; + + pushFollow(FOLLOW_logic_in_moduleClass463); + logic2=logic(); + + state._fsp--; + + match(input,LESS,FOLLOW_LESS_in_moduleClass465); + match(input,70,FOLLOW_70_in_moduleClass467); + match(input,GREATER,FOLLOW_GREATER_in_moduleClass469); + + for(Entry e : VarCountMap.entrySet()){ + if(e.getValue() == 0){ + System.out.println("warning: variable '" + e.getKey() + "' is never assigned"); + } + } + + // create new lpn + // Zone zone; + // if (Main.ZONE_VERSION == 2) { + // zone = new HashedHashedMapZoneImpl(); + // } + // else if (Main.ZONE_VERSION == 3) { + // zone = new HashedHashedMapZoneImpl(); + // } + // else { + // zone = new HashedHashedMapZoneImpl(); + // } + + int[] initialMarking = new int[(logic2!=null?logic2.initMarking:null).size()]; + + int i = 0; + for(Integer mark : (logic2!=null?logic2.initMarking:null)){ + initialMarking[i++] = mark; + } + + lpn = new PlatuLPN(prj, (modName!=null?modName.getText():null), Inputs, Outputs, Internals, VarNodeMap, (logic2!=null?logic2.lpnTranSet:null), + StatevectorMap, initialMarking); + + lpn.addAllInputTrans(inputTranList); + lpn.addAllOutputTrans(outputTranList); + lpn.setVarIndexMap(VarIndexMap); + (logic2!=null?logic2.lpnTranSet:null).setLPN(lpn); + + LpnMap.put(lpn.getLabel(), lpn); + lpn.setArgumentList(argumentList); + + + } + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return lpn; + } + // $ANTLR end "moduleClass" + + + // $ANTLR start "constants" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:480:1: constants : '<' 'const' '>' (const1= ID '=' val1= INT ';' )* '<' '/const' '>' ; + public final void constants() { + Token const1=null; + Token val1=null; + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:481:2: ( '<' 'const' '>' (const1= ID '=' val1= INT ';' )* '<' '/const' '>' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:481:4: '<' 'const' '>' (const1= ID '=' val1= INT ';' )* '<' '/const' '>' + { + match(input,LESS,FOLLOW_LESS_in_constants494); + match(input,71,FOLLOW_71_in_constants496); + match(input,GREATER,FOLLOW_GREATER_in_constants498); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:481:20: (const1= ID '=' val1= INT ';' )* + loop15: + do { + int alt15=2; + int LA15_0 = input.LA(1); + + if ( (LA15_0==ID) ) { + alt15=1; + } + + + switch (alt15) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:481:21: const1= ID '=' val1= INT ';' + { + const1=(Token)match(input,ID,FOLLOW_ID_in_constants503); + match(input,EQUALS,FOLLOW_EQUALS_in_constants505); + val1=(Token)match(input,INT,FOLLOW_INT_in_constants509); + + // make sure constant is not defined as something else + if(VarNodeMap.containsKey((const1!=null?const1.getText():null))){ + System.err.println("error on line " + (const1!=null?const1.getLine():null) + ": " + (const1!=null?const1.getText():null) + " already exists as a variable"); + System.exit(1); + } + else if(GlobalConstHashMap.containsKey((const1!=null?const1.getText():null))){ + System.err.println("error on line " + (const1!=null?const1.getLine():null) + ": " + (const1!=null?const1.getText():null) + " already exists as a global constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey((const1!=null?const1.getText():null))){ + System.err.println("error on line " + (const1!=null?const1.getLine():null) + ": " + (const1!=null?const1.getText():null) + " is already defined as a global variable"); + System.exit(1); + } + + // put will override previous value + Integer result = ConstHashMap.put((const1!=null?const1.getText():null), Integer.parseInt((val1!=null?val1.getText():null))); + if(result != null){ + System.err.println("error on line " + (const1!=null?const1.getLine():null) + ": " + (const1!=null?const1.getText():null) + " has already been defined"); + System.exit(1); + } + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_constants520); + + } + break; + + default : + break loop15; + } + } while (true); + + match(input,LESS,FOLLOW_LESS_in_constants524); + match(input,72,FOLLOW_72_in_constants526); + match(input,GREATER,FOLLOW_GREATER_in_constants528); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return ; + } + // $ANTLR end "constants" + + + // $ANTLR start "globalConstants" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:507:1: globalConstants : '<' 'const' '>' (const1= ID '=' val1= INT ';' )* '<' '/const' '>' ; + public final void globalConstants() { + Token const1=null; + Token val1=null; + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:508:5: ( '<' 'const' '>' (const1= ID '=' val1= INT ';' )* '<' '/const' '>' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:508:9: '<' 'const' '>' (const1= ID '=' val1= INT ';' )* '<' '/const' '>' + { + match(input,LESS,FOLLOW_LESS_in_globalConstants545); + match(input,71,FOLLOW_71_in_globalConstants547); + match(input,GREATER,FOLLOW_GREATER_in_globalConstants549); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:508:25: (const1= ID '=' val1= INT ';' )* + loop16: + do { + int alt16=2; + int LA16_0 = input.LA(1); + + if ( (LA16_0==ID) ) { + alt16=1; + } + + + switch (alt16) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:508:26: const1= ID '=' val1= INT ';' + { + const1=(Token)match(input,ID,FOLLOW_ID_in_globalConstants554); + match(input,EQUALS,FOLLOW_EQUALS_in_globalConstants556); + val1=(Token)match(input,INT,FOLLOW_INT_in_globalConstants560); + + // make sure constant has not been defined already + if(GlobalVarHashMap.containsKey((const1!=null?const1.getText():null))){ + System.err.println("error on line " + (const1!=null?const1.getLine():null) + ": " + (const1!=null?const1.getText():null) + " is already defined as a global variable"); + System.exit(1); + } + + // put will override previous value + Integer result = GlobalConstHashMap.put((const1!=null?const1.getText():null), Integer.parseInt((val1!=null?val1.getText():null))); + if(result != null){ + System.err.println("error on line " + (const1!=null?const1.getLine():null) + ": " + (const1!=null?const1.getText():null) + " has already been defined"); + System.exit(1); + } + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_globalConstants586); + + } + break; + + default : + break loop16; + } + } while (true); + + match(input,LESS,FOLLOW_LESS_in_globalConstants590); + match(input,72,FOLLOW_72_in_globalConstants592); + match(input,GREATER,FOLLOW_GREATER_in_globalConstants594); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return ; + } + // $ANTLR end "globalConstants" + + + // $ANTLR start "globalVariables" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:526:1: globalVariables : '<' 'var' '>' ( globalVarDecl | globalArrayDecl )+ '<' '/var' '>' ; + public final void globalVariables() { + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:527:2: ( '<' 'var' '>' ( globalVarDecl | globalArrayDecl )+ '<' '/var' '>' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:527:4: '<' 'var' '>' ( globalVarDecl | globalArrayDecl )+ '<' '/var' '>' + { + match(input,LESS,FOLLOW_LESS_in_globalVariables608); + match(input,INTERNAL,FOLLOW_INTERNAL_in_globalVariables610); + match(input,GREATER,FOLLOW_GREATER_in_globalVariables612); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:527:18: ( globalVarDecl | globalArrayDecl )+ + int cnt17=0; + loop17: + do { + int alt17=3; + int LA17_0 = input.LA(1); + + if ( (LA17_0==ID) ) { + int LA17_2 = input.LA(2); + + if ( (LA17_2==EQUALS) ) { + alt17=1; + } + else if ( (LA17_2==68) ) { + alt17=2; + } + + + } + + + switch (alt17) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:527:19: globalVarDecl + { + pushFollow(FOLLOW_globalVarDecl_in_globalVariables615); + globalVarDecl(); + + state._fsp--; + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:527:35: globalArrayDecl + { + pushFollow(FOLLOW_globalArrayDecl_in_globalVariables619); + globalArrayDecl(); + + state._fsp--; + + + } + break; + + default : + if ( cnt17 >= 1 ) break loop17; + EarlyExitException eee = + new EarlyExitException(17, input); + throw eee; + } + cnt17++; + } while (true); + + match(input,LESS,FOLLOW_LESS_in_globalVariables623); + match(input,73,FOLLOW_73_in_globalVariables625); + match(input,GREATER,FOLLOW_GREATER_in_globalVariables627); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return ; + } + // $ANTLR end "globalVariables" + + + // $ANTLR start "globalVarDecl" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:530:1: globalVarDecl : var= ID '=' (val= INT | var2= ID ) ';' ; + public final void globalVarDecl() { + Token var=null; + Token val=null; + Token var2=null; + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:531:2: (var= ID '=' (val= INT | var2= ID ) ';' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:531:4: var= ID '=' (val= INT | var2= ID ) ';' + { + var=(Token)match(input,ID,FOLLOW_ID_in_globalVarDecl640); + if (var==null) return; + + // make sure global variables are consistently defined in each lpn file + if(GlobalSize == 0){ + if(GlobalConstHashMap.containsKey(var.getText())){ + System.err.println("error on line" + var.getLine() + ": " + var.getText() + "already exists as a constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey(var.getText())){ + System.err.println("error on line " + var.getLine() + ": " + var.getText() + " has already been defined"); + System.exit(1); + } + } + else{ + if(!GlobalVarHashMap.containsKey(var.getText())){ + System.err.println("error on line " + var.getLine() + ": " + var.getText() + " is inconsistently defined"); + System.exit(1); + } + } + + GlobalCount++; + + match(input,EQUALS,FOLLOW_EQUALS_in_globalVarDecl650); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:553:7: (val= INT | var2= ID ) + int alt18=2; + int LA18_0 = input.LA(1); + + if ( (LA18_0==INT) ) { + alt18=1; + } + else if ( (LA18_0==ID) ) { + alt18=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 18, 0, input); + + throw nvae; + } + switch (alt18) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:553:8: val= INT + { + val=(Token)match(input,INT,FOLLOW_INT_in_globalVarDecl655); + if (val==null) return; + + // make sure global variables are consistently initialized + int value = Integer.parseInt(val.getText()); + if(GlobalSize == 0){ + GlobalVarHashMap.put(var.getText(), value); + } + else{ + int globalVal = GlobalVarHashMap.get(var.getText()); + if(globalVal != value){ + System.err.println("error on line " + val.getLine() + ": " + var.getText() + " is inconsistently assigned"); + System.exit(1); + } + } + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:568:5: var2= ID + { + var2=(Token)match(input,ID,FOLLOW_ID_in_globalVarDecl669); + + // get value of variable + Integer value = null; + if(GlobalConstHashMap.containsKey((var2!=null?var2.getText():null))){ + value = GlobalConstHashMap.get((var2!=null?var2.getText():null)); + } + else if(GlobalVarHashMap.containsKey((var2!=null?var2.getText():null))){ + System.err.println("error on line " + (var2!=null?var2.getLine():null) + ": global variable " + (var2!=null?var2.getText():null) + " cannot be assigned to global variable " + var.getText()); + return; + } + else{ + System.err.println("error on line " + (var2!=null?var2.getLine():null) + ": " + (var2!=null?var2.getText():null) + " is not defined"); + return; + } + + // make sure global variable is consitently initialized + if(GlobalSize == 0){ + GlobalVarHashMap.put(var.getText(), value); + } + else{ + int globalVal = GlobalVarHashMap.get(var.getText()); + if(globalVal != value){ + System.err.println("error on line " + (var2!=null?var2.getLine():null) + ": " + var.getText() + " is inconsistently assigned"); + System.exit(1); + } + } + + + } + break; + + } + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_globalVarDecl680); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return ; + } + // $ANTLR end "globalVarDecl" + + + // $ANTLR start "globalArrayDecl" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:599:1: globalArrayDecl : arrayVar= ID ( '[' (arrayExpr= expression ) ']' )+ ';' ; + public final void globalArrayDecl() { + Token arrayVar=null; + PlatuInstParser.expression_return arrayExpr = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:600:2: (arrayVar= ID ( '[' (arrayExpr= expression ) ']' )+ ';' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:600:4: arrayVar= ID ( '[' (arrayExpr= expression ) ']' )+ ';' + { + arrayVar=(Token)match(input,ID,FOLLOW_ID_in_globalArrayDecl694); + + List dimensionList = new ArrayList(); + + // make sure global variables are consistently defined in each lpn file + if(GlobalSize == 0){ + if(GlobalConstHashMap.containsKey((arrayVar!=null?arrayVar.getText():null))){ + System.err.println("error on line" + (arrayVar!=null?arrayVar.getLine():null) + ": " + (arrayVar!=null?arrayVar.getText():null) + "already exists as a constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey((arrayVar!=null?arrayVar.getText():null))){ + System.err.println("error on line " + (arrayVar!=null?arrayVar.getLine():null) + ": " + (arrayVar!=null?arrayVar.getText():null) + " has already been defined"); + System.exit(1); + } + } + else{ + if(!GlobalVarHashMap.containsKey((arrayVar!=null?arrayVar.getText():null))){ + System.err.println("error on line " + (arrayVar!=null?arrayVar.getLine():null) + ": " + (arrayVar!=null?arrayVar.getText():null) + " is inconsistently defined"); + System.exit(1); + } + } + + GlobalCount++; + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:624:3: ( '[' (arrayExpr= expression ) ']' )+ + int cnt19=0; + loop19: + do { + int alt19=2; + int LA19_0 = input.LA(1); + + if ( (LA19_0==68) ) { + alt19=1; + } + + + switch (alt19) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:624:4: '[' (arrayExpr= expression ) ']' + { + match(input,68,FOLLOW_68_in_globalArrayDecl704); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:624:8: (arrayExpr= expression ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:624:9: arrayExpr= expression + { + pushFollow(FOLLOW_expression_in_globalArrayDecl709); + arrayExpr=expression(); + + state._fsp--; + + + dimensionList.add((arrayExpr!=null?arrayExpr.value:0)); + + + } + + match(input,69,FOLLOW_69_in_globalArrayDecl721); + + } + break; + + default : + if ( cnt19 >= 1 ) break loop19; + EarlyExitException eee = + new EarlyExitException(19, input); + throw eee; + } + cnt19++; + } while (true); + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_globalArrayDecl725); + + // make sure global variables are consistently initialized + if(GlobalSize == 0){ + GlobalVarHashMap.put((arrayVar!=null?arrayVar.getText():null), 0); + GlobalVarNodeMap.put((arrayVar!=null?arrayVar.getText():null), new ArrayNode((arrayVar!=null?arrayVar.getText():null), null, dimensionList.size(), dimensionList, null)); + } + else{ + ArrayNode node = (ArrayNode) GlobalVarNodeMap.get((arrayVar!=null?arrayVar.getText():null)); + if(node.getDimensions() != dimensionList.size()){ + error("error on line " + (arrayVar!=null?arrayVar.getLine():null) + ": " + (arrayVar!=null?arrayVar.getText():null) + " is inconsistently assigned"); + } + + List dimList = node.getDimensionList(); + for(int i = 0; i < dimensionList.size(); i++){ + if(dimList.get(i) != dimensionList.get(i)){ + error("error on line " + (arrayVar!=null?arrayVar.getLine():null) + ": " + (arrayVar!=null?arrayVar.getText():null) + " is inconsistently assigned"); + } + } + } + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return ; + } + // $ANTLR end "globalArrayDecl" + + + // $ANTLR start "variables" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:650:1: variables : '<' 'var' '>' ( varDecl | arrayDecl )+ '<' '/var' '>' ; + public final void variables() { + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:651:2: ( '<' 'var' '>' ( varDecl | arrayDecl )+ '<' '/var' '>' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:651:4: '<' 'var' '>' ( varDecl | arrayDecl )+ '<' '/var' '>' + { + match(input,LESS,FOLLOW_LESS_in_variables741); + match(input,INTERNAL,FOLLOW_INTERNAL_in_variables743); + match(input,GREATER,FOLLOW_GREATER_in_variables745); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:651:18: ( varDecl | arrayDecl )+ + int cnt20=0; + loop20: + do { + int alt20=3; + int LA20_0 = input.LA(1); + + if ( (LA20_0==ID) ) { + int LA20_2 = input.LA(2); + + if ( (LA20_2==EQUALS) ) { + alt20=1; + } + else if ( (LA20_2==68) ) { + alt20=2; + } + + + } + + + switch (alt20) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:651:20: varDecl + { + pushFollow(FOLLOW_varDecl_in_variables749); + varDecl(); + + state._fsp--; + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:651:30: arrayDecl + { + pushFollow(FOLLOW_arrayDecl_in_variables753); + arrayDecl(); + + state._fsp--; + + + } + break; + + default : + if ( cnt20 >= 1 ) break loop20; + EarlyExitException eee = + new EarlyExitException(20, input); + throw eee; + } + cnt20++; + } while (true); + + match(input,LESS,FOLLOW_LESS_in_variables757); + match(input,73,FOLLOW_73_in_variables759); + match(input,GREATER,FOLLOW_GREATER_in_variables761); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return ; + } + // $ANTLR end "variables" + + + // $ANTLR start "varDecl" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:654:1: varDecl : var= ID '=' (val= INT | var2= ID ) ';' ; + public final void varDecl() { + Token var=null; + Token val=null; + Token var2=null; + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:655:2: (var= ID '=' (val= INT | var2= ID ) ';' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:655:4: var= ID '=' (val= INT | var2= ID ) ';' + { + Integer value = null; Token varNode = null; + var=(Token)match(input,ID,FOLLOW_ID_in_varDecl778); + + // check variable is unique in scope + if(GlobalConstHashMap.containsKey((var!=null?var.getText():null))){ + System.err.println("error on line " + (var!=null?var.getLine():null) + ": " + (var!=null?var.getText():null) + " is a global constant"); + System.exit(1); + } + else if(GlobalVarHashMap.containsKey((var!=null?var.getText():null))){ + System.err.println("error on line " + (var!=null?var.getLine():null) + ": " + (var!=null?var.getText():null) + " is a global variable"); + System.exit(1); + } + else if(VarNodeMap.containsKey((var!=null?var.getText():null))){ + System.err.println("error on line " + (var!=null?var.getLine():null) + ": " + (var!=null?var.getText():null) + " has already been defined"); + System.exit(1); + } + + varNode = var; + + match(input,EQUALS,FOLLOW_EQUALS_in_varDecl788); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:674:7: (val= INT | var2= ID ) + int alt21=2; + int LA21_0 = input.LA(1); + + if ( (LA21_0==INT) ) { + alt21=1; + } + else if ( (LA21_0==ID) ) { + alt21=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 21, 0, input); + + throw nvae; + } + switch (alt21) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:674:8: val= INT + { + val=(Token)match(input,INT,FOLLOW_INT_in_varDecl793); + + // get variable initial value + value = Integer.parseInt((val!=null?val.getText():null)); + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:679:5: var2= ID + { + var2=(Token)match(input,ID,FOLLOW_ID_in_varDecl807); + + // get variable initial value + if(GlobalConstHashMap.containsKey((var2!=null?var2.getText():null))){ + value = GlobalConstHashMap.get((var2!=null?var2.getText():null)); + } + else if(GlobalVarHashMap.containsKey((var2!=null?var2.getText():null))){ + value = GlobalVarHashMap.get((var2!=null?var2.getText():null)); + } + else if(ConstHashMap.containsKey((var2!=null?var2.getText():null))){ + value = ConstHashMap.get((var2!=null?var2.getText():null)); + } + else if(StatevectorMap.containsKey((var2!=null?var2.getText():null))){ // Should var be allowed to assign a var? + value = StatevectorMap.get((var!=null?var.getText():null)); + } + else{ + System.err.println("error on line " + (var2!=null?var2.getLine():null) + ": " + (var2!=null?var2.getText():null) + " is not defined or is not compatible"); + System.exit(1); + } + + varNode = var2; + + + } + break; + + } + + if (varNode != null) { + // add variable and value to state vector + StatevectorMap.put(varNode.getText(), value); + + // generate variable index and create new var node + int index = VariableIndex++; + VarIndexMap.insert(varNode.getText(), index); + + VarNode internalVar = new VarNode(varNode.getText(), index); + internalVar.setType(VarType.INTERNAL); + VarNodeMap.put(varNode.getText(), internalVar); + VarCountMap.put(varNode.getText(), 0); + + Internals.add(varNode.getText()); + } + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_varDecl826); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return ; + } + // $ANTLR end "varDecl" + + + // $ANTLR start "arrayDecl" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:720:1: arrayDecl : var= ID ( '[' (arrayExpr= expression ) ']' )+ ( '=' '{' (val2= INT | var2= ID )+ '}' )? ';' ; + public final void arrayDecl() { + Token var=null; + Token val2=null; + Token var2=null; + PlatuInstParser.expression_return arrayExpr = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:721:2: (var= ID ( '[' (arrayExpr= expression ) ']' )+ ( '=' '{' (val2= INT | var2= ID )+ '}' )? ';' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:721:4: var= ID ( '[' (arrayExpr= expression ) ']' )+ ( '=' '{' (val2= INT | var2= ID )+ '}' )? ';' + { + var=(Token)match(input,ID,FOLLOW_ID_in_arrayDecl840); + + List dimensionList = new ArrayList(); + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:725:3: ( '[' (arrayExpr= expression ) ']' )+ + int cnt22=0; + loop22: + do { + int alt22=2; + int LA22_0 = input.LA(1); + + if ( (LA22_0==68) ) { + alt22=1; + } + + + switch (alt22) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:725:4: '[' (arrayExpr= expression ) ']' + { + match(input,68,FOLLOW_68_in_arrayDecl851); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:725:8: (arrayExpr= expression ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:725:9: arrayExpr= expression + { + pushFollow(FOLLOW_expression_in_arrayDecl856); + arrayExpr=expression(); + + state._fsp--; + + + dimensionList.add((arrayExpr!=null?arrayExpr.value:0)); + + + } + + match(input,69,FOLLOW_69_in_arrayDecl867); + + } + break; + + default : + if ( cnt22 >= 1 ) break loop22; + EarlyExitException eee = + new EarlyExitException(22, input); + throw eee; + } + cnt22++; + } while (true); + + + int iter = dimensionList.size() - 1; + int dIndex = 0; + int arraySize = dimensionList.get(dIndex++); + int lastSize = 0; + List topLevelArray = new ArrayList(arraySize); + + Queue> arrayQueue = new LinkedList>(); + arrayQueue.offer(topLevelArray); + + while(iter > 0){ + lastSize = arraySize; + arraySize = dimensionList.get(dIndex++); + int qSize = arrayQueue.size(); + for(int i = 0; i < qSize; i++){ + List array = arrayQueue.poll(); + for(int j = 0 ; j < lastSize; j++){ + List newArray = new ArrayList(arraySize); + array.add(j, newArray); + arrayQueue.offer(newArray); + } + } + + iter--; + } + + int varCount = 0; + dIndex--; + arraySize = dimensionList.get(dIndex); + + List varList = new ArrayList(); + while(!arrayQueue.isEmpty()){ + List array = arrayQueue.poll(); + for(int i = 0; i < arraySize; i++){ + String name = (var!=null?var.getText():null) + "." + varCount; + varCount++; + + int index = VariableIndex++; + VarNode element = new VarNode(name, index); + element.setType(VarType.INTERNAL); + array.add(i, element); + varList.add(element); + + // add variable and value to state vector + StatevectorMap.put(name, 0); + + // generate variable index and create new var node + VarIndexMap.insert(name, index); + VarNodeMap.put(name, element); + } + } + + ArrayNode newArray = new ArrayNode((var!=null?var.getText():null), topLevelArray, dimensionList.size(), dimensionList, varList); + newArray.setType(VarType.INTERNAL); + VarNodeMap.put((var!=null?var.getText():null), newArray); + VarCountMap.put((var!=null?var.getText():null), 0); + Internals.add((var!=null?var.getText():null)); + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:788:3: ( '=' '{' (val2= INT | var2= ID )+ '}' )? + int alt24=2; + int LA24_0 = input.LA(1); + + if ( (LA24_0==EQUALS) ) { + alt24=1; + } + switch (alt24) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:788:4: '=' '{' (val2= INT | var2= ID )+ '}' + { + match(input,EQUALS,FOLLOW_EQUALS_in_arrayDecl879); + + List valueList = new ArrayList(); + + match(input,74,FOLLOW_74_in_arrayDecl889); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:792:7: (val2= INT | var2= ID )+ + int cnt23=0; + loop23: + do { + int alt23=3; + int LA23_0 = input.LA(1); + + if ( (LA23_0==INT) ) { + alt23=1; + } + else if ( (LA23_0==ID) ) { + alt23=2; + } + + + switch (alt23) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:792:8: val2= INT + { + val2=(Token)match(input,INT,FOLLOW_INT_in_arrayDecl894); + if (val2==null) return; + + Integer dimVal = Integer.parseInt(val2.getText()); + if(dimVal < 1){ + error("error on line " + val2.getLine() + ": invalid dimension"); + } + + valueList.add(dimVal); + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:801:5: var2= ID + { + var2=(Token)match(input,ID,FOLLOW_ID_in_arrayDecl908); + + Integer initVal = null; + + // get variable initial value + if(GlobalConstHashMap.containsKey((var2!=null?var2.getText():null))){ + initVal = GlobalConstHashMap.get((var2!=null?var2.getText():null)); + } + else if(GlobalVarHashMap.containsKey((var2!=null?var2.getText():null))){ + initVal = GlobalVarHashMap.get((var2!=null?var2.getText():null)); + } + else if(ConstHashMap.containsKey((var2!=null?var2.getText():null))){ + initVal = ConstHashMap.get((var2!=null?var2.getText():null)); + } + else if(StatevectorMap.containsKey((var2!=null?var2.getText():null))){ // Should var be allowed to assign a var? + initVal = StatevectorMap.get((var2!=null?var2.getText():null)); + } + else{ + System.err.println("error on line " + (var2!=null?var2.getLine():null) + ": " + (var2!=null?var2.getText():null) + " is not defined"); + return; + } + + if(initVal < 1){ + error("error on line " + (var2!=null?var2.getLine():null) + ": invalid dimension"); + } + + valueList.add(initVal); + + + } + break; + + default : + if ( cnt23 >= 1 ) break loop23; + EarlyExitException eee = + new EarlyExitException(23, input); + throw eee; + } + cnt23++; + } while (true); + + match(input,75,FOLLOW_75_in_arrayDecl920); + + //TODO: (original) initialize array + //int dimensions = dimensionList.size(); + + + } + break; + + } + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_arrayDecl932); + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return ; + } + // $ANTLR end "arrayDecl" + + + // $ANTLR start "instantiation" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:837:1: instantiation : (modName= ID instName= ID '(' ( (var= MEMBER ',' )* var2= MEMBER )? ')' ';' )+ ; + public final void instantiation() { + Token modName=null; + Token instName=null; + Token var=null; + Token var2=null; + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:838:5: ( (modName= ID instName= ID '(' ( (var= MEMBER ',' )* var2= MEMBER )? ')' ';' )+ ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:838:7: (modName= ID instName= ID '(' ( (var= MEMBER ',' )* var2= MEMBER )? ')' ';' )+ + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:838:7: (modName= ID instName= ID '(' ( (var= MEMBER ',' )* var2= MEMBER )? ')' ';' )+ + int cnt27=0; + loop27: + do { + int alt27=2; + int LA27_0 = input.LA(1); + + if ( (LA27_0==ID) ) { + alt27=1; + } + + + switch (alt27) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:838:8: modName= ID instName= ID '(' ( (var= MEMBER ',' )* var2= MEMBER )? ')' ';' + { + modName=(Token)match(input,ID,FOLLOW_ID_in_instantiation950); + instName=(Token)match(input,ID,FOLLOW_ID_in_instantiation954); + + List argList = new ArrayList(); + List modList = new ArrayList(); + + match(input,LPAREN,FOLLOW_LPAREN_in_instantiation970); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:843:9: ( (var= MEMBER ',' )* var2= MEMBER )? + int alt26=2; + int LA26_0 = input.LA(1); + + if ( (LA26_0==MEMBER) ) { + alt26=1; + } + switch (alt26) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:843:10: (var= MEMBER ',' )* var2= MEMBER + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:843:10: (var= MEMBER ',' )* + loop25: + do { + int alt25=2; + int LA25_0 = input.LA(1); + + if ( (LA25_0==MEMBER) ) { + int LA25_1 = input.LA(2); + + if ( (LA25_1==COMMA) ) { + alt25=1; + } + + + } + + + switch (alt25) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:843:11: var= MEMBER ',' + { + var=(Token)match(input,MEMBER,FOLLOW_MEMBER_in_instantiation975); + match(input,COMMA,FOLLOW_COMMA_in_instantiation977); + + String buffer = (var!=null?var.getText():null); + StringTokenizer tk = new StringTokenizer(buffer, "."); + + String module = tk.nextToken(); + String variable = tk.nextToken(); + + modList.add(module); + argList.add(module + "." + variable); + + + } + break; + + default : + break loop25; + } + } while (true); + + var2=(Token)match(input,MEMBER,FOLLOW_MEMBER_in_instantiation997); + + String buffer = (var2!=null?var2.getText():null); + StringTokenizer tk = new StringTokenizer(buffer, "."); + + String module = tk.nextToken(); + String variable = tk.nextToken(); + + modList.add(module); + argList.add(module + "." + variable); + + + } + break; + + } + + match(input,RPAREN,FOLLOW_RPAREN_in_instantiation1015); + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_instantiation1017); + + Instance inst = new Instance((modName!=null?modName.getText():null), (instName!=null?instName.getText():null), argList, modList); + InstanceList.add(inst); + + + } + break; + + default : + if ( cnt27 >= 1 ) break loop27; + EarlyExitException eee = + new EarlyExitException(27, input); + throw eee; + } + cnt27++; + } while (true); + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return ; + } + // $ANTLR end "instantiation" + + public static class logic_return extends ParserRuleReturnScope { + public List initMarking; + public LpnTranList lpnTranSet; + } + + // $ANTLR start "logic" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:873:1: logic returns [List initMarking, LpnTranList lpnTranSet] : marking ( transition )+ ; + public final PlatuInstParser.logic_return logic() { + PlatuInstParser.logic_return retval = new PlatuInstParser.logic_return(); + retval.start = input.LT(1); + + LPNTran transition3 = null; + + List marking4 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:874:5: ( marking ( transition )+ ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:874:9: marking ( transition )+ + { + retval.lpnTranSet = new LpnTranList(); + pushFollow(FOLLOW_marking_in_logic1063); + marking4=marking(); + + state._fsp--; + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:875:14: ( transition )+ + int cnt28=0; + loop28: + do { + int alt28=2; + int LA28_0 = input.LA(1); + + if ( (LA28_0==LESS) ) { + int LA28_1 = input.LA(2); + + if ( (LA28_1==TRANSITION) ) { + alt28=1; + } + + + } + + + switch (alt28) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:875:15: transition + { + pushFollow(FOLLOW_transition_in_logic1066); + transition3=transition(); + + state._fsp--; + + retval.lpnTranSet.add(transition3); + + } + break; + + default : + if ( cnt28 >= 1 ) break loop28; + EarlyExitException eee = + new EarlyExitException(28, input); + throw eee; + } + cnt28++; + } while (true); + + + retval.initMarking = marking4; + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "logic" + + + // $ANTLR start "marking" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:881:1: marking returns [List mark] : ( '<' 'marking' '>' ( (m1= INT | c1= ID ) ( ',' (m2= INT | c2= ID ) )* )? '<' '/marking' '>' )? ; + public final List marking() { + List mark = null; + + Token m1=null; + Token c1=null; + Token m2=null; + Token c2=null; + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:882:5: ( ( '<' 'marking' '>' ( (m1= INT | c1= ID ) ( ',' (m2= INT | c2= ID ) )* )? '<' '/marking' '>' )? ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:882:9: ( '<' 'marking' '>' ( (m1= INT | c1= ID ) ( ',' (m2= INT | c2= ID ) )* )? '<' '/marking' '>' )? + { + mark = new LinkedList(); Integer result; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:883:9: ( '<' 'marking' '>' ( (m1= INT | c1= ID ) ( ',' (m2= INT | c2= ID ) )* )? '<' '/marking' '>' )? + int alt33=2; + int LA33_0 = input.LA(1); + + if ( (LA33_0==LESS) ) { + int LA33_1 = input.LA(2); + + if ( (LA33_1==MARKING) ) { + alt33=1; + } + } + switch (alt33) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:883:10: '<' 'marking' '>' ( (m1= INT | c1= ID ) ( ',' (m2= INT | c2= ID ) )* )? '<' '/marking' '>' + { + match(input,LESS,FOLLOW_LESS_in_marking1119); + match(input,MARKING,FOLLOW_MARKING_in_marking1121); + match(input,GREATER,FOLLOW_GREATER_in_marking1123); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:883:28: ( (m1= INT | c1= ID ) ( ',' (m2= INT | c2= ID ) )* )? + int alt32=2; + int LA32_0 = input.LA(1); + + if ( ((LA32_0>=ID && LA32_0<=INT)) ) { + alt32=1; + } + switch (alt32) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:883:29: (m1= INT | c1= ID ) ( ',' (m2= INT | c2= ID ) )* + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:883:29: (m1= INT | c1= ID ) + int alt29=2; + int LA29_0 = input.LA(1); + + if ( (LA29_0==INT) ) { + alt29=1; + } + else if ( (LA29_0==ID) ) { + alt29=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 29, 0, input); + + throw nvae; + } + switch (alt29) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:883:30: m1= INT + { + m1=(Token)match(input,INT,FOLLOW_INT_in_marking1129); + + mark.add(Integer.parseInt((m1!=null?m1.getText():null))); + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:887:11: c1= ID + { + c1=(Token)match(input,ID,FOLLOW_ID_in_marking1155); + + result = ConstHashMap.get((c1!=null?c1.getText():null)); + if(result == null){ + System.err.println("error on line " + (c1!=null?c1.getLine():null) + ": " + (c1!=null?c1.getText():null) + " is not a valid constant"); + System.exit(1); + } + + mark.add(result); + + + } + break; + + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:897:11: ( ',' (m2= INT | c2= ID ) )* + loop31: + do { + int alt31=2; + int LA31_0 = input.LA(1); + + if ( (LA31_0==COMMA) ) { + alt31=1; + } + + + switch (alt31) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:897:12: ',' (m2= INT | c2= ID ) + { + match(input,COMMA,FOLLOW_COMMA_in_marking1179); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:897:16: (m2= INT | c2= ID ) + int alt30=2; + int LA30_0 = input.LA(1); + + if ( (LA30_0==INT) ) { + alt30=1; + } + else if ( (LA30_0==ID) ) { + alt30=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 30, 0, input); + + throw nvae; + } + switch (alt30) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:897:17: m2= INT + { + m2=(Token)match(input,INT,FOLLOW_INT_in_marking1184); + + mark.add(Integer.parseInt((m2!=null?m2.getText():null))); + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:901:11: c2= ID + { + c2=(Token)match(input,ID,FOLLOW_ID_in_marking1210); + + result = ConstHashMap.get((c2!=null?c2.getText():null)); + if(result == null){ + System.err.println("error on line " + (c2!=null?c2.getLine():null) + ": " + (c2!=null?c2.getText():null) + " is not a valid constant"); + System.exit(1); + } + + mark.add(result); + + + } + break; + + } + + + } + break; + + default : + break loop31; + } + } while (true); + + + } + break; + + } + + match(input,LESS,FOLLOW_LESS_in_marking1237); + match(input,76,FOLLOW_76_in_marking1239); + match(input,GREATER,FOLLOW_GREATER_in_marking1241); + + } + break; + + } + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return mark; + } + // $ANTLR end "marking" + + + // $ANTLR start "transition" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:914:1: transition returns [LPNTran lpnTran] : '<' 'transition' 'label' '=' '\"' lbl= ( ID | INT ) '\"' 'preset' '=' ( '\"' '\"' | ( '\"' (pre= INT | pre1= ID ) ( ',' pre2= INT | ',' pre3= ID )* '\"' ) ) 'postset' '=' ( '\"' '\"' | ( '\"' (post= INT | post1= ID ) ( ( ',' post2= INT ) | ( ',' post3= ID ) )* '\"' ) ) '>' ( guard )? ( delay )? ( ( assertion ) | ( assignment ) )* '<' '/transition' '>' ; + public final LPNTran transition() { + LPNTran lpnTran = null; + + Token lbl=null; + Token pre=null; + Token pre1=null; + Token pre2=null; + Token pre3=null; + Token post=null; + Token post1=null; + Token post2=null; + Token post3=null; + Expression guard5 = null; + + PlatuInstParser.delay_return delay6 = null; + + Expression assertion7 = null; + + VarExpr assignment8 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:915:5: ( '<' 'transition' 'label' '=' '\"' lbl= ( ID | INT ) '\"' 'preset' '=' ( '\"' '\"' | ( '\"' (pre= INT | pre1= ID ) ( ',' pre2= INT | ',' pre3= ID )* '\"' ) ) 'postset' '=' ( '\"' '\"' | ( '\"' (post= INT | post1= ID ) ( ( ',' post2= INT ) | ( ',' post3= ID ) )* '\"' ) ) '>' ( guard )? ( delay )? ( ( assertion ) | ( assignment ) )* '<' '/transition' '>' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:915:10: '<' 'transition' 'label' '=' '\"' lbl= ( ID | INT ) '\"' 'preset' '=' ( '\"' '\"' | ( '\"' (pre= INT | pre1= ID ) ( ',' pre2= INT | ',' pre3= ID )* '\"' ) ) 'postset' '=' ( '\"' '\"' | ( '\"' (post= INT | post1= ID ) ( ( ',' post2= INT ) | ( ',' post3= ID ) )* '\"' ) ) '>' ( guard )? ( delay )? ( ( assertion ) | ( assignment ) )* '<' '/transition' '>' + { + + Integer result = null; + ArrayList presetList = new ArrayList(); + ArrayList postsetList = new ArrayList(); + VarExprList assignmentList = new VarExprList(); + ArrayList assertionList = new ArrayList(); + Expression guardExpr = TrueExpr; + int delayLB = 0; + int delayUB = INFINITY; + boolean local = true; + + match(input,LESS,FOLLOW_LESS_in_transition1275); + match(input,TRANSITION,FOLLOW_TRANSITION_in_transition1277); + match(input,LABEL,FOLLOW_LABEL_in_transition1279); + match(input,EQUALS,FOLLOW_EQUALS_in_transition1281); + match(input,QUOTE,FOLLOW_QUOTE_in_transition1283); + lbl=input.LT(1); + if ( (input.LA(1)>=ID && input.LA(1)<=INT) ) { + input.consume(); + state.errorRecovery=false; + } + else { + MismatchedSetException mse = new MismatchedSetException(null,input); + throw mse; + } + + match(input,QUOTE,FOLLOW_QUOTE_in_transition1293); + match(input,PRESET,FOLLOW_PRESET_in_transition1295); + match(input,EQUALS,FOLLOW_EQUALS_in_transition1297); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:926:69: ( '\"' '\"' | ( '\"' (pre= INT | pre1= ID ) ( ',' pre2= INT | ',' pre3= ID )* '\"' ) ) + int alt36=2; + int LA36_0 = input.LA(1); + + if ( (LA36_0==QUOTE) ) { + int LA36_1 = input.LA(2); + + if ( (LA36_1==QUOTE) ) { + alt36=1; + } + else if ( ((LA36_1>=ID && LA36_1<=INT)) ) { + alt36=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 36, 1, input); + + throw nvae; + } + } + else { + NoViableAltException nvae = + new NoViableAltException("", 36, 0, input); + + throw nvae; + } + switch (alt36) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:926:70: '\"' '\"' + { + match(input,QUOTE,FOLLOW_QUOTE_in_transition1300); + match(input,QUOTE,FOLLOW_QUOTE_in_transition1302); + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:926:80: ( '\"' (pre= INT | pre1= ID ) ( ',' pre2= INT | ',' pre3= ID )* '\"' ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:926:80: ( '\"' (pre= INT | pre1= ID ) ( ',' pre2= INT | ',' pre3= ID )* '\"' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:926:81: '\"' (pre= INT | pre1= ID ) ( ',' pre2= INT | ',' pre3= ID )* '\"' + { + match(input,QUOTE,FOLLOW_QUOTE_in_transition1307); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:926:85: (pre= INT | pre1= ID ) + int alt34=2; + int LA34_0 = input.LA(1); + + if ( (LA34_0==INT) ) { + alt34=1; + } + else if ( (LA34_0==ID) ) { + alt34=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 34, 0, input); + + throw nvae; + } + switch (alt34) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:926:86: pre= INT + { + pre=(Token)match(input,INT,FOLLOW_INT_in_transition1312); + + presetList.add(Integer.parseInt((pre!=null?pre.getText():null))); + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:930:7: pre1= ID + { + pre1=(Token)match(input,ID,FOLLOW_ID_in_transition1332); + + result = ConstHashMap.get((pre1!=null?pre1.getText():null)); + if(result == null){ + System.err.println("error on line " + (pre1!=null?pre1.getLine():null) + ": " + (pre1!=null?pre1.getText():null) + " is not a constant"); + System.exit(1); + } + + presetList.add(result); + + + } + break; + + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:940:6: ( ',' pre2= INT | ',' pre3= ID )* + loop35: + do { + int alt35=3; + int LA35_0 = input.LA(1); + + if ( (LA35_0==COMMA) ) { + int LA35_2 = input.LA(2); + + if ( (LA35_2==INT) ) { + alt35=1; + } + else if ( (LA35_2==ID) ) { + alt35=2; + } + + + } + + + switch (alt35) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:940:8: ',' pre2= INT + { + match(input,COMMA,FOLLOW_COMMA_in_transition1348); + pre2=(Token)match(input,INT,FOLLOW_INT_in_transition1352); + + presetList.add(Integer.parseInt((pre2!=null?pre2.getText():null))); + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:944:7: ',' pre3= ID + { + match(input,COMMA,FOLLOW_COMMA_in_transition1370); + pre3=(Token)match(input,ID,FOLLOW_ID_in_transition1374); + + result = ConstHashMap.get((pre3!=null?pre3.getText():null)); + if(result == null){ + System.err.println("error on line " + (pre3!=null?pre3.getLine():null) + ": " + (pre3!=null?pre3.getText():null) + " is not a constant"); + System.exit(1); + } + + presetList.add(result); + + + } + break; + + default : + break loop35; + } + } while (true); + + match(input,QUOTE,FOLLOW_QUOTE_in_transition1389); + + } + + + } + break; + + } + + match(input,POSTSET,FOLLOW_POSTSET_in_transition1393); + match(input,EQUALS,FOLLOW_EQUALS_in_transition1395); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:954:27: ( '\"' '\"' | ( '\"' (post= INT | post1= ID ) ( ( ',' post2= INT ) | ( ',' post3= ID ) )* '\"' ) ) + int alt39=2; + int LA39_0 = input.LA(1); + + if ( (LA39_0==QUOTE) ) { + int LA39_1 = input.LA(2); + + if ( (LA39_1==QUOTE) ) { + alt39=1; + } + else if ( ((LA39_1>=ID && LA39_1<=INT)) ) { + alt39=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 39, 1, input); + + throw nvae; + } + } + else { + NoViableAltException nvae = + new NoViableAltException("", 39, 0, input); + + throw nvae; + } + switch (alt39) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:954:29: '\"' '\"' + { + match(input,QUOTE,FOLLOW_QUOTE_in_transition1399); + match(input,QUOTE,FOLLOW_QUOTE_in_transition1401); + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:954:39: ( '\"' (post= INT | post1= ID ) ( ( ',' post2= INT ) | ( ',' post3= ID ) )* '\"' ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:954:39: ( '\"' (post= INT | post1= ID ) ( ( ',' post2= INT ) | ( ',' post3= ID ) )* '\"' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:954:40: '\"' (post= INT | post1= ID ) ( ( ',' post2= INT ) | ( ',' post3= ID ) )* '\"' + { + match(input,QUOTE,FOLLOW_QUOTE_in_transition1406); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:954:44: (post= INT | post1= ID ) + int alt37=2; + int LA37_0 = input.LA(1); + + if ( (LA37_0==INT) ) { + alt37=1; + } + else if ( (LA37_0==ID) ) { + alt37=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 37, 0, input); + + throw nvae; + } + switch (alt37) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:954:46: post= INT + { + post=(Token)match(input,INT,FOLLOW_INT_in_transition1412); + + postsetList.add(Integer.parseInt((post!=null?post.getText():null))); + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:958:8: post1= ID + { + post1=(Token)match(input,ID,FOLLOW_ID_in_transition1432); + + result = ConstHashMap.get((post1!=null?post1.getText():null)); + if(result == null){ + System.err.println("error on line " + (post1!=null?post1.getLine():null) + ": " + (post1!=null?post1.getText():null) + " is not a constant"); + System.exit(1); + } + + postsetList.add(result); + + + } + break; + + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:969:6: ( ( ',' post2= INT ) | ( ',' post3= ID ) )* + loop38: + do { + int alt38=3; + int LA38_0 = input.LA(1); + + if ( (LA38_0==COMMA) ) { + int LA38_2 = input.LA(2); + + if ( (LA38_2==INT) ) { + alt38=1; + } + else if ( (LA38_2==ID) ) { + alt38=2; + } + + + } + + + switch (alt38) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:969:8: ( ',' post2= INT ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:969:8: ( ',' post2= INT ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:969:9: ',' post2= INT + { + match(input,COMMA,FOLLOW_COMMA_in_transition1457); + post2=(Token)match(input,INT,FOLLOW_INT_in_transition1461); + + postsetList.add(Integer.parseInt((post2!=null?post2.getText():null))); + + + } + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:973:10: ( ',' post3= ID ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:973:10: ( ',' post3= ID ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:973:11: ',' post3= ID + { + match(input,COMMA,FOLLOW_COMMA_in_transition1482); + post3=(Token)match(input,ID,FOLLOW_ID_in_transition1485); + + result = ConstHashMap.get((post3!=null?post3.getText():null)); + if(result == null){ + System.err.println("error on line " + (post3!=null?post3.getLine():null) + ": " + (post3!=null?post3.getText():null) + " is not a constant"); + System.exit(1); + } + + postsetList.add(result); + + + } + + + } + break; + + default : + break loop38; + } + } while (true); + + match(input,QUOTE,FOLLOW_QUOTE_in_transition1504); + + } + + + } + break; + + } + + match(input,GREATER,FOLLOW_GREATER_in_transition1509); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:983:21: ( guard )? + int alt40=2; + int LA40_0 = input.LA(1); + + if ( (LA40_0==79) ) { + alt40=1; + } + switch (alt40) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:983:22: guard + { + pushFollow(FOLLOW_guard_in_transition1512); + guard5=guard(); + + state._fsp--; + + + guardExpr = guard5; + + + } + break; + + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:987:9: ( delay )? + int alt41=2; + int LA41_0 = input.LA(1); + + if ( (LA41_0==80) ) { + alt41=1; + } + switch (alt41) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:987:10: delay + { + pushFollow(FOLLOW_delay_in_transition1532); + delay6=delay(); + + state._fsp--; + + + delayLB = (delay6!=null?delay6.delayLB:0); + delayUB = (delay6!=null?delay6.delayUB:0); + + + } + break; + + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:992:9: ( ( assertion ) | ( assignment ) )* + loop42: + do { + int alt42=3; + int LA42_0 = input.LA(1); + + if ( (LA42_0==78) ) { + alt42=1; + } + else if ( (LA42_0==ID) ) { + alt42=2; + } + + + switch (alt42) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:992:10: ( assertion ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:992:10: ( assertion ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:992:11: assertion + { + pushFollow(FOLLOW_assertion_in_transition1553); + assertion7=assertion(); + + state._fsp--; + + + if(assertion7 != null){ + assertionList.add(assertion7); + } + + + } + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:998:10: ( assignment ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:998:10: ( assignment ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:998:11: assignment + { + pushFollow(FOLLOW_assignment_in_transition1573); + assignment8=assignment(); + + state._fsp--; + + + assignmentList.add(assignment8); + + + } + + + } + break; + + default : + break loop42; + } + } while (true); + + match(input,LESS,FOLLOW_LESS_in_transition1593); + match(input,77,FOLLOW_77_in_transition1595); + match(input,GREATER,FOLLOW_GREATER_in_transition1597); + + // create new lpn transitions and add assertions + lpnTran = new LPNTran((lbl!=null?lbl.getText():null), TransitionIndex++, presetList, postsetList, guardExpr, assignmentList, delayLB, delayUB, local); + if(assertionList.size() > 0){ + lpnTran.addAllAssertions(assertionList); + } + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return lpnTran; + } + // $ANTLR end "transition" + + + // $ANTLR start "assertion" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1012:1: assertion returns [Expression booleanExpr] : 'assert' '(' expression ')' ';' ; + public final Expression assertion() { + Expression booleanExpr = null; + + PlatuInstParser.expression_return expression9 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1013:2: ( 'assert' '(' expression ')' ';' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1013:4: 'assert' '(' expression ')' ';' + { + match(input,78,FOLLOW_78_in_assertion1631); + match(input,LPAREN,FOLLOW_LPAREN_in_assertion1633); + pushFollow(FOLLOW_expression_in_assertion1635); + expression9=expression(); + + state._fsp--; + + match(input,RPAREN,FOLLOW_RPAREN_in_assertion1637); + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_assertion1639); + + booleanExpr = new Expression((expression9!=null?expression9.expr:null)); + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return booleanExpr; + } + // $ANTLR end "assertion" + + + // $ANTLR start "guard" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1020:1: guard returns [Expression expr] : 'condition' '(' expression ')' ';' ; + public final Expression guard() { + Expression expr = null; + + PlatuInstParser.expression_return expression10 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1021:5: ( 'condition' '(' expression ')' ';' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1021:8: 'condition' '(' expression ')' ';' + { + match(input,79,FOLLOW_79_in_guard1664); + match(input,LPAREN,FOLLOW_LPAREN_in_guard1666); + pushFollow(FOLLOW_expression_in_guard1668); + expression10=expression(); + + state._fsp--; + + match(input,RPAREN,FOLLOW_RPAREN_in_guard1670); + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_guard1672); + + expr = new Expression((expression10!=null?expression10.expr:null)); + + + } + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return expr; + } + // $ANTLR end "guard" + + public static class delay_return extends ParserRuleReturnScope { + public int delayLB; + public int delayUB; + } + + // $ANTLR start "delay" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1027:1: delay returns [int delayLB, int delayUB] : 'delay' '(' lb= INT ',' (ub= INT | 'inf' ) ')' ';' ; + public final PlatuInstParser.delay_return delay() { + PlatuInstParser.delay_return retval = new PlatuInstParser.delay_return(); + retval.start = input.LT(1); + + Token lb=null; + Token ub=null; + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1028:5: ( 'delay' '(' lb= INT ',' (ub= INT | 'inf' ) ')' ';' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1028:8: 'delay' '(' lb= INT ',' (ub= INT | 'inf' ) ')' ';' + { + match(input,80,FOLLOW_80_in_delay1706); + match(input,LPAREN,FOLLOW_LPAREN_in_delay1708); + lb=(Token)match(input,INT,FOLLOW_INT_in_delay1712); + if (lb==null) return null; + + retval.delayLB = Integer.parseInt(lb.getText()); + + match(input,COMMA,FOLLOW_COMMA_in_delay1726); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1032:8: (ub= INT | 'inf' ) + int alt43=2; + int LA43_0 = input.LA(1); + + if ( (LA43_0==INT) ) { + alt43=1; + } + else if ( (LA43_0==81) ) { + alt43=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 43, 0, input); + + throw nvae; + } + switch (alt43) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1032:9: ub= INT + { + ub=(Token)match(input,INT,FOLLOW_INT_in_delay1731); + if (ub==null) return null; + + retval.delayUB = Integer.parseInt(ub.getText()); + // make sure delays are >= 0 and upper bound is >= lower bound + if(retval.delayLB < 0){ + System.err.println("error on line " + lb.getLine() + ": lower bound " + retval.delayLB + " must be >= 0"); + System.exit(1); + } + else if(retval.delayLB == INFINITY){ + System.err.println("error on line " + ub.getLine() + ": lower bound " + retval.delayUB + " must be a non-negative finite number"); + System.exit(1); + } + else if(retval.delayUB < retval.delayLB){ + System.err.println("error on line " + ub.getLine() + ": upper bound " + retval.delayUB + " < lower bound " + retval.delayLB); + System.exit(1); + } + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1049:6: 'inf' + { + match(input,81,FOLLOW_81_in_delay1746); + + retval.delayUB = INFINITY; + + + } + break; + + } + + match(input,RPAREN,FOLLOW_RPAREN_in_delay1759); + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_delay1761); + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "delay" + + + // $ANTLR start "assignment" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1056:1: assignment returns [VarExpr assign] : ( (var1= ID '=' var2= ID ) | (var= ID '=' varExpr= expression ';' ) | (arrayVar= ID ( '[' (arrayExpr= expression ) ']' )+ '=' assignExpr= expression ';' ) ); + public final VarExpr assignment() { + VarExpr assign = null; + + Token var1=null; + Token var2=null; + Token var=null; + Token arrayVar=null; + PlatuInstParser.expression_return varExpr = null; + + PlatuInstParser.expression_return arrayExpr = null; + + PlatuInstParser.expression_return assignExpr = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1057:5: ( (var1= ID '=' var2= ID ) | (var= ID '=' varExpr= expression ';' ) | (arrayVar= ID ( '[' (arrayExpr= expression ) ']' )+ '=' assignExpr= expression ';' ) ) + int alt45=3; + int LA45_0 = input.LA(1); + + if ( (LA45_0==ID) ) { + int LA45_1 = input.LA(2); + + if ( (LA45_1==EQUALS) ) { + int LA45_2 = input.LA(3); + + if ( (LA45_2==ID) ) { + switch ( input.LA(4) ) { + case LESS: + { + int LA45_6 = input.LA(5); + + if ( (LA45_6==77) ) { + alt45=1; + } + else if ( ((LA45_6>=ID && LA45_6<=INT)||LA45_6==LPAREN||(LA45_6>=TRUE && LA45_6<=FALSE)||(LA45_6>=PLUS && LA45_6<=MINUS)||LA45_6==NEGATION||LA45_6==BITWISE_NEGATION) ) { + alt45=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 45, 6, input); + + throw nvae; + } + } + break; + case ID: + case 78: + { + alt45=1; + } + break; + case QMARK: + case SEMICOLON: + case PLUS: + case MINUS: + case TIMES: + case DIV: + case MOD: + case GREATER: + case GREATER_EQUAL: + case LESS_EQUAL: + case EQUIV: + case NOT_EQUIV: + case AND: + case OR: + case IMPLICATION: + case BITWISE_AND: + case BITWISE_OR: + case BITWISE_XOR: + case BITWISE_LSHIFT: + case BITWISE_RSHIFT: + case 68: + { + alt45=2; + } + break; + default: + NoViableAltException nvae = + new NoViableAltException("", 45, 4, input); + + throw nvae; + } + + } + else if ( (LA45_2==INT||LA45_2==LPAREN||(LA45_2>=TRUE && LA45_2<=FALSE)||(LA45_2>=PLUS && LA45_2<=MINUS)||LA45_2==NEGATION||LA45_2==BITWISE_NEGATION) ) { + alt45=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 45, 2, input); + + throw nvae; + } + } + else if ( (LA45_1==68) ) { + alt45=3; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 45, 1, input); + + throw nvae; + } + } + else { + NoViableAltException nvae = + new NoViableAltException("", 45, 0, input); + + throw nvae; + } + switch (alt45) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1057:9: (var1= ID '=' var2= ID ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1057:9: (var1= ID '=' var2= ID ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1057:10: var1= ID '=' var2= ID + { + var1=(Token)match(input,ID,FOLLOW_ID_in_assignment1787); + match(input,EQUALS,FOLLOW_EQUALS_in_assignment1789); + var2=(Token)match(input,ID,FOLLOW_ID_in_assignment1793); + + } + + + // make sure only global, internal and output variables are assigned + if(GlobalConstHashMap.containsKey((var1!=null?var1.getText():null))){ + System.err.println("error on line " + (var1!=null?var1.getLine():null) + ": global constant " + (var1!=null?var1.getText():null) + " cannot be assigned"); + System.exit(1); + } + else if(ConstHashMap.containsKey((var1!=null?var1.getText():null))){ + System.err.println("error on line " + (var1!=null?var1.getLine():null) + ": constant " + (var1!=null?var1.getText():null) + " cannot be assigned"); + System.exit(1); + } + else if(!VarNodeMap.containsKey((var1!=null?var1.getText():null))){ + System.err.println("error on line " + (var1!=null?var1.getLine():null) + ": variable " + (var1!=null?var1.getText():null) + " was not declared"); + System.exit(1); + } + else if(!Outputs.contains((var1!=null?var1.getText():null)) && !Internals.contains((var1!=null?var1.getText():null))){ + System.err.println("error on line " + (var1!=null?var1.getLine():null) + ": input variable " + (var1!=null?var1.getText():null) + " cannot be assigned"); + System.exit(1); + } + + ExpressionNode node2 = null; + if(GlobalConstHashMap.containsKey((var2!=null?var2.getText():null))){ + node2 = new ConstNode((var2!=null?var2.getText():null), GlobalConstHashMap.get((var2!=null?var2.getText():null))); + } + else if(ConstHashMap.containsKey((var2!=null?var2.getText():null))){ + node2 = new ConstNode((var2!=null?var2.getText():null), ConstHashMap.get((var2!=null?var2.getText():null))); + } + else if(GlobalVarHashMap.containsKey((var2!=null?var2.getText():null))){ + node2 = VarNodeMap.get((var2!=null?var2.getText():null)); + } + else if(!VarNodeMap.containsKey((var2!=null?var2.getText():null))){ + System.err.println("error on line " + (var2!=null?var2.getLine():null) + ": variable " + (var2!=null?var2.getText():null) + " was not declared"); + return null; + } + else{ + node2 = VarNodeMap.get((var2!=null?var2.getText():null)); + } + + VarNode node1 = VarNodeMap.get((var1!=null?var1.getText():null)); + if(ArrayNode.class.isAssignableFrom(node1.getClass())){ + if(!ArrayNode.class.isAssignableFrom(node2.getClass())){ + System.err.println("error on line " + (var1!=null?var1.getLine():null) + ": variable " + (var1!=null?var1.getText():null) + " is an array"); + System.exit(1); + } + + ArrayNode arrayNode1 = (ArrayNode) node1; + ArrayNode arrayNode2 = (ArrayNode) node2; + + List dimensionList1 = arrayNode1.getDimensionList(); + List dimensionList2 = arrayNode2.getDimensionList(); + + if(dimensionList1.size() != dimensionList2.size()){ + System.err.println("error on line " + (var1!=null?var1.getLine():null) + ": incompatible array dimensions"); + System.exit(1); + } + + for(int i = 0; i < dimensionList1.size(); i++){ + if(dimensionList1.get(i) != dimensionList2.get(i)){ + System.err.println("error on line " + (var1!=null?var1.getLine():null) + ": incompatible array dimensions"); + System.exit(1); + } + } + + //TODO: (original) array to array assignment + + }else if(ArrayNode.class.isAssignableFrom(node2.getClass())){ + System.err.println("error on line " + (var2!=null?var2.getLine():null) + ": variable " + (var2!=null?var2.getText():null) + " is an array"); + System.exit(1); + } + else{ + // regular assignment + Expression expr = new Expression(node2); + assign = new VarExpr(node1, expr); + } + + if(node1.getType() == VarType.INTERNAL || node1.getType() == VarType.OUTPUT){ + Integer varCount = VarCountMap.get((var1!=null?var1.getText():null)); + VarCountMap.put((var1!=null?var1.getText():null), ++varCount); + } + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1137:8: (var= ID '=' varExpr= expression ';' ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1137:8: (var= ID '=' varExpr= expression ';' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1137:9: var= ID '=' varExpr= expression ';' + { + var=(Token)match(input,ID,FOLLOW_ID_in_assignment1815); + match(input,EQUALS,FOLLOW_EQUALS_in_assignment1817); + + // make sure only global, internal and output variables are assigned + if(GlobalConstHashMap.containsKey((var!=null?var.getText():null))){ + System.err.println("error on line " + (var!=null?var.getLine():null) + ": global constant " + (var!=null?var.getText():null) + " cannot be assigned"); + System.exit(1); + } + else if(ConstHashMap.containsKey((var!=null?var.getText():null))){ + System.err.println("error on line " + (var!=null?var.getLine():null) + ": constant " + (var!=null?var.getText():null) + " cannot be assigned"); + System.exit(1); + } + else if(!VarNodeMap.containsKey((var!=null?var.getText():null))){ + System.err.println("error on line " + (var!=null?var.getLine():null) + ": variable " + (var!=null?var.getText():null) + " was not declared"); + System.exit(1); + } + else if(!Outputs.contains((var!=null?var.getText():null)) && !Internals.contains((var!=null?var.getText():null))){ + System.err.println("error on line " + (var!=null?var.getLine():null) + ": input variable " + (var!=null?var.getText():null) + " cannot be assigned"); + System.exit(1); + } + + pushFollow(FOLLOW_expression_in_assignment1835); + varExpr=expression(); + + state._fsp--; + + + Expression expr = new Expression((varExpr!=null?varExpr.expr:null)); + VarNode node = VarNodeMap.get((var!=null?var.getText():null)); + if(ArrayNode.class.isAssignableFrom(node.getClass())){ + System.err.println("error on line " + (var!=null?var.getLine():null) + ": variable " + (var!=null?var.getText():null) + " is an array"); + System.exit(1); + } + + if(node.getType() == VarType.INTERNAL || node.getType() == VarType.OUTPUT){ + Integer varCount = VarCountMap.get((var!=null?var.getText():null)); + VarCountMap.put((var!=null?var.getText():null), ++varCount); + } + + assign = new VarExpr(node, expr); + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_assignment1850); + + } + + + } + break; + case 3 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1173:13: (arrayVar= ID ( '[' (arrayExpr= expression ) ']' )+ '=' assignExpr= expression ';' ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1173:13: (arrayVar= ID ( '[' (arrayExpr= expression ) ']' )+ '=' assignExpr= expression ';' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1173:14: arrayVar= ID ( '[' (arrayExpr= expression ) ']' )+ '=' assignExpr= expression ';' + { + arrayVar=(Token)match(input,ID,FOLLOW_ID_in_assignment1858); + + List indexList = new ArrayList(); + + // make sure only global, internal and output variables are assigned + if(GlobalConstHashMap.containsKey((arrayVar!=null?arrayVar.getText():null))){ + System.err.println("error on line " + (arrayVar!=null?arrayVar.getLine():null) + ": global constant " + (arrayVar!=null?arrayVar.getText():null) + " cannot be assigned"); + System.exit(1); + } + else if(ConstHashMap.containsKey((arrayVar!=null?arrayVar.getText():null))){ + System.err.println("error on line " + (arrayVar!=null?arrayVar.getLine():null) + ": constant " + (arrayVar!=null?arrayVar.getText():null) + " cannot be assigned"); + System.exit(1); + } + else if(!VarNodeMap.containsKey((arrayVar!=null?arrayVar.getText():null))){ + System.err.println("error on line " + (arrayVar!=null?arrayVar.getLine():null) + ": variable " + (arrayVar!=null?arrayVar.getText():null) + " was not declared"); + System.exit(1); + } + else if(!Outputs.contains((arrayVar!=null?arrayVar.getText():null)) && !Internals.contains((arrayVar!=null?arrayVar.getText():null))){ + System.err.println("error on line " + (arrayVar!=null?arrayVar.getLine():null) + ": input variable " + (arrayVar!=null?arrayVar.getText():null) + " cannot be assigned"); + System.exit(1); + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1195:6: ( '[' (arrayExpr= expression ) ']' )+ + int cnt44=0; + loop44: + do { + int alt44=2; + int LA44_0 = input.LA(1); + + if ( (LA44_0==68) ) { + alt44=1; + } + + + switch (alt44) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1195:7: '[' (arrayExpr= expression ) ']' + { + match(input,68,FOLLOW_68_in_assignment1875); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1195:11: (arrayExpr= expression ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1195:12: arrayExpr= expression + { + pushFollow(FOLLOW_expression_in_assignment1880); + arrayExpr=expression(); + + state._fsp--; + + + ExpressionNode node = (arrayExpr!=null?arrayExpr.expr:null); + indexList.add(node); + + + } + + match(input,69,FOLLOW_69_in_assignment1897); + + } + break; + + default : + if ( cnt44 >= 1 ) break loop44; + EarlyExitException eee = + new EarlyExitException(44, input); + throw eee; + } + cnt44++; + } while (true); + + match(input,EQUALS,FOLLOW_EQUALS_in_assignment1901); + pushFollow(FOLLOW_expression_in_assignment1905); + assignExpr=expression(); + + state._fsp--; + + + Expression expr = new Expression((assignExpr!=null?assignExpr.expr:null)); + VarNode arrayNode = VarNodeMap.get((arrayVar!=null?arrayVar.getText():null)); + if(ArrayNode.class.isAssignableFrom(arrayNode.getClass())){ + assign = new VarExpr(new ArrayElement((ArrayNode) arrayNode, indexList), expr); + } + else{ + System.err.println("error on line " + (arrayVar!=null?arrayVar.getLine():null) + ": " + (arrayVar!=null?arrayVar.getText():null) + " is not an array"); + System.exit(1); + } + + if(arrayNode.getType() == VarType.INTERNAL || arrayNode.getType() == VarType.OUTPUT){ + Integer varCount = VarCountMap.get((arrayVar!=null?arrayVar.getText():null)); + VarCountMap.put((arrayVar!=null?arrayVar.getText():null), ++varCount); + } + + match(input,SEMICOLON,FOLLOW_SEMICOLON_in_assignment1920); + + } + + + } + break; + + } + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return assign; + } + // $ANTLR end "assignment" + + public static class term_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "term" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1221:1: term returns [ExpressionNode expr, int value] : (var= ID | (array= ID ( '[' (arrayExpr= expression ) ']' )+ ) | LPAREN expression RPAREN | INT | TRUE | FALSE ); + public final PlatuInstParser.term_return term() { + PlatuInstParser.term_return retval = new PlatuInstParser.term_return(); + retval.start = input.LT(1); + + Token var=null; + Token array=null; + Token INT12=null; + PlatuInstParser.expression_return arrayExpr = null; + + PlatuInstParser.expression_return expression11 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1222:5: (var= ID | (array= ID ( '[' (arrayExpr= expression ) ']' )+ ) | LPAREN expression RPAREN | INT | TRUE | FALSE ) + int alt47=6; + switch ( input.LA(1) ) { + case ID: + { + int LA47_1 = input.LA(2); + + if ( (LA47_1==RPAREN||(LA47_1>=QMARK && LA47_1<=SEMICOLON)||(LA47_1>=PLUS && LA47_1<=MOD)||(LA47_1>=GREATER && LA47_1<=NOT_EQUIV)||(LA47_1>=AND && LA47_1<=IMPLICATION)||(LA47_1>=BITWISE_AND && LA47_1<=BITWISE_RSHIFT)||LA47_1==69) ) { + alt47=1; + } + else if ( (LA47_1==68) ) { + alt47=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 47, 1, input); + + throw nvae; + } + } + break; + case LPAREN: + { + alt47=3; + } + break; + case INT: + { + alt47=4; + } + break; + case TRUE: + { + alt47=5; + } + break; + case FALSE: + { + alt47=6; + } + break; + default: + NoViableAltException nvae = + new NoViableAltException("", 47, 0, input); + + throw nvae; + } + + switch (alt47) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1222:9: var= ID + { + var=(Token)match(input,ID,FOLLOW_ID_in_term1951); + + if(ConstHashMap.containsKey((var!=null?var.getText():null))){ + retval.value = ConstHashMap.get((var!=null?var.getText():null)); + retval.expr = new ConstNode((var!=null?var.getText():null), retval.value); + } + else if(GlobalConstHashMap.containsKey((var!=null?var.getText():null))){ + retval.value = GlobalConstHashMap.get((var!=null?var.getText():null)); + retval.expr = new ConstNode((var!=null?var.getText():null), retval.value); + } + else if(StatevectorMap.containsKey((var!=null?var.getText():null))){ + retval.value = StatevectorMap.get((var!=null?var.getText():null)); + retval.expr = VarNodeMap.get((var!=null?var.getText():null)); + } + else if(GlobalVarHashMap.containsKey((var!=null?var.getText():null))){ + retval.value = StatevectorMap.get((var!=null?var.getText():null)); + retval.expr = VarNodeMap.get((var!=null?var.getText():null)); + } + else if(VarNodeMap.containsKey((var!=null?var.getText():null))){ + System.err.println("error on line " + (var!=null?var.getLine():null) + ": variable " + (var!=null?var.getText():null) + " is an array"); + System.exit(1); + } + else{ + System.err.println("error on line " + (var!=null?var.getLine():null) + ": variable " + (var!=null?var.getText():null) + " is not valid"); + System.exit(1); + } + + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1249:6: (array= ID ( '[' (arrayExpr= expression ) ']' )+ ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1249:6: (array= ID ( '[' (arrayExpr= expression ) ']' )+ ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1249:7: array= ID ( '[' (arrayExpr= expression ) ']' )+ + { + array=(Token)match(input,ID,FOLLOW_ID_in_term1970); + + List indexList = new ArrayList(); + List valueList = new ArrayList(); + VarNode arrayNode = null; + + if(!VarNodeMap.containsKey((array!=null?array.getText():null))){ + System.err.println("error on line " + (array!=null?array.getLine():null) + ": " + (array!=null?array.getText():null) + " is not a valid array"); + System.exit(1); + } + + arrayNode = VarNodeMap.get((array!=null?array.getText():null)); + if(!ArrayNode.class.isAssignableFrom(arrayNode.getClass())){ + System.err.println("error on line " + (array!=null?array.getLine():null) + ": " + (array!=null?array.getText():null) + " is not a valid array"); + System.exit(1); + } + + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1266:6: ( '[' (arrayExpr= expression ) ']' )+ + int cnt46=0; + loop46: + do { + int alt46=2; + int LA46_0 = input.LA(1); + + if ( (LA46_0==68) ) { + alt46=1; + } + + + switch (alt46) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1266:7: '[' (arrayExpr= expression ) ']' + { + match(input,68,FOLLOW_68_in_term1986); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1266:11: (arrayExpr= expression ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1266:12: arrayExpr= expression + { + pushFollow(FOLLOW_expression_in_term1991); + arrayExpr=expression(); + + state._fsp--; + + + ExpressionNode node = (arrayExpr!=null?arrayExpr.expr:null); + indexList.add(node); + valueList.add((arrayExpr!=null?arrayExpr.value:0)); + + + } + + match(input,69,FOLLOW_69_in_term2006); + + } + break; + + default : + if ( cnt46 >= 1 ) break loop46; + EarlyExitException eee = + new EarlyExitException(46, input); + throw eee; + } + cnt46++; + } while (true); + + + String name = ((ArrayNode) arrayNode).getElement(valueList).getName(); + retval.value = StatevectorMap.get(name); + retval.expr = new ArrayElement((ArrayNode) arrayNode, indexList); + + + } + + + } + break; + case 3 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1279:9: LPAREN expression RPAREN + { + match(input,LPAREN,FOLLOW_LPAREN_in_term2031); + pushFollow(FOLLOW_expression_in_term2033); + expression11=expression(); + + state._fsp--; + + match(input,RPAREN,FOLLOW_RPAREN_in_term2035); + retval.expr = (expression11!=null?expression11.expr:null); retval.value = (expression11!=null?expression11.value:0); + + } + break; + case 4 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1280:9: INT + { + INT12=(Token)match(input,INT,FOLLOW_INT_in_term2047); + retval.value = Integer.parseInt((INT12!=null?INT12.getText():null)); retval.expr = new ConstNode("name", retval.value); + + } + break; + case 5 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1281:9: TRUE + { + match(input,TRUE,FOLLOW_TRUE_in_term2059); + retval.expr = ONE; retval.value = 1; + + } + break; + case 6 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1282:9: FALSE + { + match(input,FALSE,FOLLOW_FALSE_in_term2071); + retval.expr = ZERO; retval.value = 0; + + } + break; + + } + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "term" + + public static class unary_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "unary" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1285:1: unary returns [ExpressionNode expr, int value] : ( '+' | ( '-' ) )* term ; + public final PlatuInstParser.unary_return unary() { + PlatuInstParser.unary_return retval = new PlatuInstParser.unary_return(); + retval.start = input.LT(1); + + PlatuInstParser.term_return term13 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1286:5: ( ( '+' | ( '-' ) )* term ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1286:9: ( '+' | ( '-' ) )* term + { + boolean positive = true; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1287:6: ( '+' | ( '-' ) )* + loop48: + do { + int alt48=3; + int LA48_0 = input.LA(1); + + if ( (LA48_0==PLUS) ) { + alt48=1; + } + else if ( (LA48_0==MINUS) ) { + alt48=2; + } + + + switch (alt48) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1287:7: '+' + { + match(input,PLUS,FOLLOW_PLUS_in_unary2108); + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1287:13: ( '-' ) + { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1287:13: ( '-' ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1287:14: '-' + { + match(input,MINUS,FOLLOW_MINUS_in_unary2113); + if(positive){ positive = false;} else {positive = true;} + + } + + + } + break; + + default : + break loop48; + } + } while (true); + + pushFollow(FOLLOW_term_in_unary2120); + term13=term(); + + state._fsp--; + + + if(!positive){ + retval.expr = new MinNode((term13!=null?term13.expr:null)); + retval.value = -(term13!=null?term13.value:0); + } + else{ + retval.expr = (term13!=null?term13.expr:null); + retval.value = (term13!=null?term13.value:0); + } + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "unary" + + public static class bitwiseNegation_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "bitwiseNegation" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1300:1: bitwiseNegation returns [ExpressionNode expr, int value] : ( '~' )* unary ; + public final PlatuInstParser.bitwiseNegation_return bitwiseNegation() { + PlatuInstParser.bitwiseNegation_return retval = new PlatuInstParser.bitwiseNegation_return(); + retval.start = input.LT(1); + + PlatuInstParser.unary_return unary14 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1301:2: ( ( '~' )* unary ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1301:5: ( '~' )* unary + { + boolean neg = false; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1302:3: ( '~' )* + loop49: + do { + int alt49=2; + int LA49_0 = input.LA(1); + + if ( (LA49_0==BITWISE_NEGATION) ) { + alt49=1; + } + + + switch (alt49) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1302:4: '~' + { + match(input,BITWISE_NEGATION,FOLLOW_BITWISE_NEGATION_in_bitwiseNegation2151); + if(neg){neg = false;} else{neg = true;} + + } + break; + + default : + break loop49; + } + } while (true); + + pushFollow(FOLLOW_unary_in_bitwiseNegation2157); + unary14=unary(); + + state._fsp--; + + + if(neg){ + retval.expr = new BitNegNode((unary14!=null?unary14.expr:null)); + retval.value = ~(unary14!=null?unary14.value:0); + } + else{ + retval.expr = (unary14!=null?unary14.expr:null); + retval.value = (unary14!=null?unary14.value:0); + } + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "bitwiseNegation" + + public static class negation_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "negation" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1315:1: negation returns [ExpressionNode expr, int value] : ( '!' )* bitwiseNegation ; + public final PlatuInstParser.negation_return negation() { + PlatuInstParser.negation_return retval = new PlatuInstParser.negation_return(); + retval.start = input.LT(1); + + PlatuInstParser.bitwiseNegation_return bitwiseNegation15 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1316:2: ( ( '!' )* bitwiseNegation ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1316:4: ( '!' )* bitwiseNegation + { + boolean neg = false; + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1317:3: ( '!' )* + loop50: + do { + int alt50=2; + int LA50_0 = input.LA(1); + + if ( (LA50_0==NEGATION) ) { + alt50=1; + } + + + switch (alt50) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1317:4: '!' + { + match(input,NEGATION,FOLLOW_NEGATION_in_negation2183); + if(neg){neg = false;} else{neg = true;} + + } + break; + + default : + break loop50; + } + } while (true); + + pushFollow(FOLLOW_bitwiseNegation_in_negation2189); + bitwiseNegation15=bitwiseNegation(); + + state._fsp--; + + + if(neg){ + retval.expr = new NegNode((bitwiseNegation15!=null?bitwiseNegation15.expr:null)); + retval.value = (bitwiseNegation15!=null?bitwiseNegation15.value:0) == 0 ? 1 : 0; + } + else{ + retval.expr = (bitwiseNegation15!=null?bitwiseNegation15.expr:null); + retval.value = (bitwiseNegation15!=null?bitwiseNegation15.value:0); + } + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "negation" + + public static class mult_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "mult" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1330:1: mult returns [ExpressionNode expr, int value] : op1= negation ( '*' op2= negation | '/' op2= negation | '%' op2= negation )* ; + public final PlatuInstParser.mult_return mult() { + PlatuInstParser.mult_return retval = new PlatuInstParser.mult_return(); + retval.start = input.LT(1); + + PlatuInstParser.negation_return op1 = null; + + PlatuInstParser.negation_return op2 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1331:5: (op1= negation ( '*' op2= negation | '/' op2= negation | '%' op2= negation )* ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1331:9: op1= negation ( '*' op2= negation | '/' op2= negation | '%' op2= negation )* + { + pushFollow(FOLLOW_negation_in_mult2217); + op1=negation(); + + state._fsp--; + + retval.expr = (op1!=null?op1.expr:null); retval.value = (op1!=null?op1.value:0); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1332:6: ( '*' op2= negation | '/' op2= negation | '%' op2= negation )* + loop51: + do { + int alt51=4; + switch ( input.LA(1) ) { + case TIMES: + { + alt51=1; + } + break; + case DIV: + { + alt51=2; + } + break; + case MOD: + { + alt51=3; + } + break; + + } + + switch (alt51) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1332:8: '*' op2= negation + { + match(input,TIMES,FOLLOW_TIMES_in_mult2229); + pushFollow(FOLLOW_negation_in_mult2233); + op2=negation(); + + state._fsp--; + + retval.expr = new MultNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = retval.value * (op2!=null?op2.value:0); + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1333:8: '/' op2= negation + { + match(input,DIV,FOLLOW_DIV_in_mult2244); + pushFollow(FOLLOW_negation_in_mult2248); + op2=negation(); + + state._fsp--; + + retval.expr = new DivNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = retval.value / (op2!=null?op2.value:0); + + } + break; + case 3 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1334:8: '%' op2= negation + { + match(input,MOD,FOLLOW_MOD_in_mult2259); + pushFollow(FOLLOW_negation_in_mult2263); + op2=negation(); + + state._fsp--; + + retval.expr = new ModNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = retval.value % (op2!=null?op2.value:0); + + } + break; + + default : + break loop51; + } + } while (true); + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "mult" + + public static class add_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "add" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1338:1: add returns [ExpressionNode expr, int value] : op1= mult ( '+' op2= mult | '-' op2= mult )* ; + public final PlatuInstParser.add_return add() { + PlatuInstParser.add_return retval = new PlatuInstParser.add_return(); + retval.start = input.LT(1); + + PlatuInstParser.mult_return op1 = null; + + PlatuInstParser.mult_return op2 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1339:5: (op1= mult ( '+' op2= mult | '-' op2= mult )* ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1339:9: op1= mult ( '+' op2= mult | '-' op2= mult )* + { + pushFollow(FOLLOW_mult_in_add2302); + op1=mult(); + + state._fsp--; + + retval.expr = (op1!=null?op1.expr:null); retval.value = (op1!=null?op1.value:0); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1340:6: ( '+' op2= mult | '-' op2= mult )* + loop52: + do { + int alt52=3; + int LA52_0 = input.LA(1); + + if ( (LA52_0==PLUS) ) { + alt52=1; + } + else if ( (LA52_0==MINUS) ) { + alt52=2; + } + + + switch (alt52) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1340:8: '+' op2= mult + { + match(input,PLUS,FOLLOW_PLUS_in_add2313); + pushFollow(FOLLOW_mult_in_add2317); + op2=mult(); + + state._fsp--; + + retval.expr = new AddNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = retval.value + (op2!=null?op2.value:0); + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1341:9: '-' op2= mult + { + match(input,MINUS,FOLLOW_MINUS_in_add2329); + pushFollow(FOLLOW_mult_in_add2333); + op2=mult(); + + state._fsp--; + + retval.expr = new SubNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = retval.value - (op2!=null?op2.value:0); + + } + break; + + default : + break loop52; + } + } while (true); + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "add" + + public static class shift_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "shift" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1345:1: shift returns [ExpressionNode expr, int value] : op1= add ( '<<' op2= add | '>>' op2= add )* ; + public final PlatuInstParser.shift_return shift() { + PlatuInstParser.shift_return retval = new PlatuInstParser.shift_return(); + retval.start = input.LT(1); + + PlatuInstParser.add_return op1 = null; + + PlatuInstParser.add_return op2 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1346:5: (op1= add ( '<<' op2= add | '>>' op2= add )* ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1346:9: op1= add ( '<<' op2= add | '>>' op2= add )* + { + pushFollow(FOLLOW_add_in_shift2372); + op1=add(); + + state._fsp--; + + retval.expr = (op1!=null?op1.expr:null); retval.value = (op1!=null?op1.value:0); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1347:6: ( '<<' op2= add | '>>' op2= add )* + loop53: + do { + int alt53=3; + int LA53_0 = input.LA(1); + + if ( (LA53_0==BITWISE_LSHIFT) ) { + alt53=1; + } + else if ( (LA53_0==BITWISE_RSHIFT) ) { + alt53=2; + } + + + switch (alt53) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1347:8: '<<' op2= add + { + match(input,BITWISE_LSHIFT,FOLLOW_BITWISE_LSHIFT_in_shift2383); + pushFollow(FOLLOW_add_in_shift2387); + op2=add(); + + state._fsp--; + + retval.expr = new LeftShiftNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = retval.value << (op2!=null?op2.value:0); + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1348:9: '>>' op2= add + { + match(input,BITWISE_RSHIFT,FOLLOW_BITWISE_RSHIFT_in_shift2399); + pushFollow(FOLLOW_add_in_shift2403); + op2=add(); + + state._fsp--; + + retval.expr = new RightShiftNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = retval.value >> (op2!=null?op2.value:0); + + } + break; + + default : + break loop53; + } + } while (true); + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "shift" + + public static class relation_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "relation" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1352:1: relation returns [ExpressionNode expr, int value] : op1= shift ( '<' op2= shift | '<=' op2= shift | '>=' op2= shift | '>' op2= shift )* ; + public final PlatuInstParser.relation_return relation() { + PlatuInstParser.relation_return retval = new PlatuInstParser.relation_return(); + retval.start = input.LT(1); + + PlatuInstParser.shift_return op1 = null; + + PlatuInstParser.shift_return op2 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1353:5: (op1= shift ( '<' op2= shift | '<=' op2= shift | '>=' op2= shift | '>' op2= shift )* ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1353:9: op1= shift ( '<' op2= shift | '<=' op2= shift | '>=' op2= shift | '>' op2= shift )* + { + pushFollow(FOLLOW_shift_in_relation2438); + op1=shift(); + + state._fsp--; + + retval.expr = (op1!=null?op1.expr:null); retval.value = (op1!=null?op1.value:0); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1354:6: ( '<' op2= shift | '<=' op2= shift | '>=' op2= shift | '>' op2= shift )* + loop54: + do { + int alt54=5; + switch ( input.LA(1) ) { + case LESS: + { + alt54=1; + } + break; + case LESS_EQUAL: + { + alt54=2; + } + break; + case GREATER_EQUAL: + { + alt54=3; + } + break; + case GREATER: + { + alt54=4; + } + break; + + } + + switch (alt54) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1354:8: '<' op2= shift + { + match(input,LESS,FOLLOW_LESS_in_relation2449); + pushFollow(FOLLOW_shift_in_relation2453); + op2=shift(); + + state._fsp--; + + retval.expr = new LessNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = (retval.value < (op2!=null?op2.value:0)) ? 1 : 0; + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1355:9: '<=' op2= shift + { + match(input,LESS_EQUAL,FOLLOW_LESS_EQUAL_in_relation2465); + pushFollow(FOLLOW_shift_in_relation2469); + op2=shift(); + + state._fsp--; + + retval.expr = new LessEqualNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = (retval.value <= (op2!=null?op2.value:0)) ? 1 : 0; + + } + break; + case 3 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1356:9: '>=' op2= shift + { + match(input,GREATER_EQUAL,FOLLOW_GREATER_EQUAL_in_relation2481); + pushFollow(FOLLOW_shift_in_relation2485); + op2=shift(); + + state._fsp--; + + retval.expr = new GreatEqualNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = (retval.value >= (op2!=null?op2.value:0)) ? 1 : 0; + + } + break; + case 4 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1357:9: '>' op2= shift + { + match(input,GREATER,FOLLOW_GREATER_in_relation2497); + pushFollow(FOLLOW_shift_in_relation2501); + op2=shift(); + + state._fsp--; + + retval.expr = new GreatNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = (retval.value > (op2!=null?op2.value:0)) ? 1 : 0; + + } + break; + + default : + break loop54; + } + } while (true); + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "relation" + + public static class equivalence_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "equivalence" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1361:1: equivalence returns [ExpressionNode expr, int value] : op1= relation ( '==' op2= relation | '!=' op2= relation )* ; + public final PlatuInstParser.equivalence_return equivalence() { + PlatuInstParser.equivalence_return retval = new PlatuInstParser.equivalence_return(); + retval.start = input.LT(1); + + PlatuInstParser.relation_return op1 = null; + + PlatuInstParser.relation_return op2 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1362:5: (op1= relation ( '==' op2= relation | '!=' op2= relation )* ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1362:9: op1= relation ( '==' op2= relation | '!=' op2= relation )* + { + pushFollow(FOLLOW_relation_in_equivalence2540); + op1=relation(); + + state._fsp--; + + retval.expr = (op1!=null?op1.expr:null); retval.value = (op1!=null?op1.value:0); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1363:6: ( '==' op2= relation | '!=' op2= relation )* + loop55: + do { + int alt55=3; + int LA55_0 = input.LA(1); + + if ( (LA55_0==EQUIV) ) { + alt55=1; + } + else if ( (LA55_0==NOT_EQUIV) ) { + alt55=2; + } + + + switch (alt55) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1363:8: '==' op2= relation + { + match(input,EQUIV,FOLLOW_EQUIV_in_equivalence2551); + pushFollow(FOLLOW_relation_in_equivalence2555); + op2=relation(); + + state._fsp--; + + retval.expr = new EquivNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = (retval.value == (op2!=null?op2.value:0)) ? 1 : 0; + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1364:8: '!=' op2= relation + { + match(input,NOT_EQUIV,FOLLOW_NOT_EQUIV_in_equivalence2566); + pushFollow(FOLLOW_relation_in_equivalence2570); + op2=relation(); + + state._fsp--; + + retval.expr = new NotEquivNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = (retval.value != (op2!=null?op2.value:0)) ? 1 : 0; + + } + break; + + default : + break loop55; + } + } while (true); + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "equivalence" + + public static class bitwiseAnd_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "bitwiseAnd" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1368:1: bitwiseAnd returns [ExpressionNode expr, int value] : op1= equivalence ( '&' op2= equivalence )* ; + public final PlatuInstParser.bitwiseAnd_return bitwiseAnd() { + PlatuInstParser.bitwiseAnd_return retval = new PlatuInstParser.bitwiseAnd_return(); + retval.start = input.LT(1); + + PlatuInstParser.equivalence_return op1 = null; + + PlatuInstParser.equivalence_return op2 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1369:5: (op1= equivalence ( '&' op2= equivalence )* ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1369:9: op1= equivalence ( '&' op2= equivalence )* + { + pushFollow(FOLLOW_equivalence_in_bitwiseAnd2609); + op1=equivalence(); + + state._fsp--; + + retval.expr = (op1!=null?op1.expr:null); retval.value = (op1!=null?op1.value:0); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1370:6: ( '&' op2= equivalence )* + loop56: + do { + int alt56=2; + int LA56_0 = input.LA(1); + + if ( (LA56_0==BITWISE_AND) ) { + alt56=1; + } + + + switch (alt56) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1370:8: '&' op2= equivalence + { + match(input,BITWISE_AND,FOLLOW_BITWISE_AND_in_bitwiseAnd2621); + pushFollow(FOLLOW_equivalence_in_bitwiseAnd2625); + op2=equivalence(); + + state._fsp--; + + retval.expr = new BitAndNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = retval.value & (op2!=null?op2.value:0); + + } + break; + + default : + break loop56; + } + } while (true); + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "bitwiseAnd" + + public static class bitwiseXor_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "bitwiseXor" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1374:1: bitwiseXor returns [ExpressionNode expr, int value] : op1= bitwiseAnd ( '^' op2= bitwiseAnd )* ; + public final PlatuInstParser.bitwiseXor_return bitwiseXor() { + PlatuInstParser.bitwiseXor_return retval = new PlatuInstParser.bitwiseXor_return(); + retval.start = input.LT(1); + + PlatuInstParser.bitwiseAnd_return op1 = null; + + PlatuInstParser.bitwiseAnd_return op2 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1375:5: (op1= bitwiseAnd ( '^' op2= bitwiseAnd )* ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1375:9: op1= bitwiseAnd ( '^' op2= bitwiseAnd )* + { + pushFollow(FOLLOW_bitwiseAnd_in_bitwiseXor2664); + op1=bitwiseAnd(); + + state._fsp--; + + retval.expr = (op1!=null?op1.expr:null); retval.value = (op1!=null?op1.value:0); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1376:6: ( '^' op2= bitwiseAnd )* + loop57: + do { + int alt57=2; + int LA57_0 = input.LA(1); + + if ( (LA57_0==BITWISE_XOR) ) { + alt57=1; + } + + + switch (alt57) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1376:8: '^' op2= bitwiseAnd + { + match(input,BITWISE_XOR,FOLLOW_BITWISE_XOR_in_bitwiseXor2675); + pushFollow(FOLLOW_bitwiseAnd_in_bitwiseXor2679); + op2=bitwiseAnd(); + + state._fsp--; + + retval.expr = new BitXorNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = retval.value ^ (op2!=null?op2.value:0); + + } + break; + + default : + break loop57; + } + } while (true); + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "bitwiseXor" + + public static class bitwiseOr_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "bitwiseOr" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1380:1: bitwiseOr returns [ExpressionNode expr, int value] : op1= bitwiseXor ( '|' op2= bitwiseXor )* ; + public final PlatuInstParser.bitwiseOr_return bitwiseOr() { + PlatuInstParser.bitwiseOr_return retval = new PlatuInstParser.bitwiseOr_return(); + retval.start = input.LT(1); + + PlatuInstParser.bitwiseXor_return op1 = null; + + PlatuInstParser.bitwiseXor_return op2 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1381:5: (op1= bitwiseXor ( '|' op2= bitwiseXor )* ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1381:9: op1= bitwiseXor ( '|' op2= bitwiseXor )* + { + pushFollow(FOLLOW_bitwiseXor_in_bitwiseOr2718); + op1=bitwiseXor(); + + state._fsp--; + + retval.expr = (op1!=null?op1.expr:null); retval.value = (op1!=null?op1.value:0); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1382:6: ( '|' op2= bitwiseXor )* + loop58: + do { + int alt58=2; + int LA58_0 = input.LA(1); + + if ( (LA58_0==BITWISE_OR) ) { + alt58=1; + } + + + switch (alt58) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1382:8: '|' op2= bitwiseXor + { + match(input,BITWISE_OR,FOLLOW_BITWISE_OR_in_bitwiseOr2729); + pushFollow(FOLLOW_bitwiseXor_in_bitwiseOr2733); + op2=bitwiseXor(); + + state._fsp--; + + retval.expr = new BitOrNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = retval.value | (op2!=null?op2.value:0); + + } + break; + + default : + break loop58; + } + } while (true); + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "bitwiseOr" + + public static class and_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "and" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1386:1: and returns [ExpressionNode expr, int value] : op1= bitwiseOr ( '&&' op2= bitwiseOr )* ; + public final PlatuInstParser.and_return and() { + PlatuInstParser.and_return retval = new PlatuInstParser.and_return(); + retval.start = input.LT(1); + + PlatuInstParser.bitwiseOr_return op1 = null; + + PlatuInstParser.bitwiseOr_return op2 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1387:5: (op1= bitwiseOr ( '&&' op2= bitwiseOr )* ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1387:9: op1= bitwiseOr ( '&&' op2= bitwiseOr )* + { + pushFollow(FOLLOW_bitwiseOr_in_and2772); + op1=bitwiseOr(); + + state._fsp--; + + retval.expr = (op1!=null?op1.expr:null); retval.value = (op1!=null?op1.value:0); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1388:6: ( '&&' op2= bitwiseOr )* + loop59: + do { + int alt59=2; + int LA59_0 = input.LA(1); + + if ( (LA59_0==AND) ) { + alt59=1; + } + + + switch (alt59) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1388:8: '&&' op2= bitwiseOr + { + match(input,AND,FOLLOW_AND_in_and2783); + pushFollow(FOLLOW_bitwiseOr_in_and2787); + op2=bitwiseOr(); + + state._fsp--; + + retval.expr = new AndNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = (retval.value != 0 && (op2!=null?op2.value:0) != 0) ? 1 : 0; + + } + break; + + default : + break loop59; + } + } while (true); + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "and" + + public static class or_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "or" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1392:1: or returns [ExpressionNode expr, int value] : op1= and ( '||' op2= and )* ; + public final PlatuInstParser.or_return or() { + PlatuInstParser.or_return retval = new PlatuInstParser.or_return(); + retval.start = input.LT(1); + + PlatuInstParser.and_return op1 = null; + + PlatuInstParser.and_return op2 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1393:5: (op1= and ( '||' op2= and )* ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1393:9: op1= and ( '||' op2= and )* + { + pushFollow(FOLLOW_and_in_or2826); + op1=and(); + + state._fsp--; + + retval.expr = (op1!=null?op1.expr:null); retval.value = (op1!=null?op1.value:0); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1394:6: ( '||' op2= and )* + loop60: + do { + int alt60=2; + int LA60_0 = input.LA(1); + + if ( (LA60_0==OR) ) { + alt60=1; + } + + + switch (alt60) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1394:8: '||' op2= and + { + match(input,OR,FOLLOW_OR_in_or2837); + pushFollow(FOLLOW_and_in_or2841); + op2=and(); + + state._fsp--; + + retval.expr = new OrNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = (retval.value != 0 || (op2!=null?op2.value:0) != 0) ? 1 : 0; + + } + break; + + default : + break loop60; + } + } while (true); + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "or" + + public static class implication_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "implication" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1398:1: implication returns [ExpressionNode expr, int value] : op1= or ( '->' op2= or )* ; + public final PlatuInstParser.implication_return implication() { + PlatuInstParser.implication_return retval = new PlatuInstParser.implication_return(); + retval.start = input.LT(1); + + PlatuInstParser.or_return op1 = null; + + PlatuInstParser.or_return op2 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1399:5: (op1= or ( '->' op2= or )* ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1399:7: op1= or ( '->' op2= or )* + { + pushFollow(FOLLOW_or_in_implication2878); + op1=or(); + + state._fsp--; + + retval.expr = (op1!=null?op1.expr:null); retval.value = (op1!=null?op1.value:0); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1400:6: ( '->' op2= or )* + loop61: + do { + int alt61=2; + int LA61_0 = input.LA(1); + + if ( (LA61_0==IMPLICATION) ) { + alt61=1; + } + + + switch (alt61) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1400:8: '->' op2= or + { + match(input,IMPLICATION,FOLLOW_IMPLICATION_in_implication2889); + pushFollow(FOLLOW_or_in_implication2893); + op2=or(); + + state._fsp--; + + retval.expr = new ImplicationNode(retval.expr, (op2!=null?op2.expr:null)); retval.value = (retval.value == 0 || (op2!=null?op2.value:0) != 0) ? 1 : 0; + + } + break; + + default : + break loop61; + } + } while (true); + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "implication" + + public static class expression_return extends ParserRuleReturnScope { + public ExpressionNode expr; + public int value; + } + + // $ANTLR start "expression" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1404:1: expression returns [ExpressionNode expr, int value] : op1= implication ( '?' op2= expression ':' op3= expression )? ; + public final PlatuInstParser.expression_return expression() { + PlatuInstParser.expression_return retval = new PlatuInstParser.expression_return(); + retval.start = input.LT(1); + + PlatuInstParser.implication_return op1 = null; + + PlatuInstParser.expression_return op2 = null; + + PlatuInstParser.expression_return op3 = null; + + + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1405:5: (op1= implication ( '?' op2= expression ':' op3= expression )? ) + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1405:9: op1= implication ( '?' op2= expression ':' op3= expression )? + { + pushFollow(FOLLOW_implication_in_expression2933); + op1=implication(); + + state._fsp--; + + retval.expr = (op1!=null?op1.expr:null); retval.value = (op1!=null?op1.value:0); + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1406:6: ( '?' op2= expression ':' op3= expression )? + int alt62=2; + int LA62_0 = input.LA(1); + + if ( (LA62_0==QMARK) ) { + alt62=1; + } + switch (alt62) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1406:7: '?' op2= expression ':' op3= expression + { + match(input,QMARK,FOLLOW_QMARK_in_expression2943); + pushFollow(FOLLOW_expression_in_expression2947); + op2=expression(); + + state._fsp--; + + match(input,COLON,FOLLOW_COLON_in_expression2949); + pushFollow(FOLLOW_expression_in_expression2953); + op3=expression(); + + state._fsp--; + + + retval.value = (retval.value != 0) ? (op2!=null?op2.value:0) : (op3!=null?op3.value:0); + retval.expr = new TernaryNode(retval.expr, (op2!=null?op2.expr:null), (op3!=null?op3.expr:null)); + + + } + break; + + } + + + } + + retval.stop = input.LT(-1); + + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return retval; + } + // $ANTLR end "expression" + + + // $ANTLR start "ctlTerm" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1415:1: ctlTerm : ( ID | LPAREN ctl LPAREN ); + public final void ctlTerm() { + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1416:2: ( ID | LPAREN ctl LPAREN ) + int alt63=2; + int LA63_0 = input.LA(1); + + if ( (LA63_0==ID) ) { + alt63=1; + } + else if ( (LA63_0==LPAREN) ) { + alt63=2; + } + else { + NoViableAltException nvae = + new NoViableAltException("", 63, 0, input); + + throw nvae; + } + switch (alt63) { + case 1 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1416:4: ID + { + match(input,ID,FOLLOW_ID_in_ctlTerm2989); + + } + break; + case 2 : + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1417:4: LPAREN ctl LPAREN + { + match(input,LPAREN,FOLLOW_LPAREN_in_ctlTerm2994); + pushFollow(FOLLOW_ctl_in_ctlTerm2996); + ctl(); + + state._fsp--; + + match(input,LPAREN,FOLLOW_LPAREN_in_ctlTerm2998); + + } + break; + + } + } + + catch (RecognitionException e){ + System.err.println(e.input.getSourceName() + ":"); + System.err.println("---> Mismatched token '" + e.token.getText() + "' on line " + e.line); + System.err.println(); + System.exit(1); + } + finally { + } + return ; + } + // $ANTLR end "ctlTerm" + + + // $ANTLR start "ctl" + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1420:1: ctl : ; + public final static void ctl() { + try { + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1421:2: () + // /Users/erodrig9/workspace/platu/src/platu/lpn/io/PlatuInst.g:1422:2: + { + } + + } + finally { + } + return ; + } + // $ANTLR end "ctl" + + // Delegated rules + + + + + public static final BitSet FOLLOW_include_in_parseLpnFile52 = new BitSet(new long[]{0x0000002000000000L}); + public static final BitSet FOLLOW_globalConstants_in_parseLpnFile55 = new BitSet(new long[]{0x0000002000000000L}); + public static final BitSet FOLLOW_globalVariables_in_parseLpnFile58 = new BitSet(new long[]{0x0000002000000000L}); + public static final BitSet FOLLOW_main_in_parseLpnFile82 = new BitSet(new long[]{0x0000002000000000L}); + public static final BitSet FOLLOW_moduleClass_in_parseLpnFile87 = new BitSet(new long[]{0x0000002000000000L}); + public static final BitSet FOLLOW_EOF_in_parseLpnFile92 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_LESS_in_include110 = new BitSet(new long[]{0x1000000000000000L}); + public static final BitSet FOLLOW_60_in_include112 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_include114 = new BitSet(new long[]{0x0000000000000010L}); + public static final BitSet FOLLOW_PATH_in_include117 = new BitSet(new long[]{0x0000000000004000L}); + public static final BitSet FOLLOW_SEMICOLON_in_include119 = new BitSet(new long[]{0x0000002000000010L}); + public static final BitSet FOLLOW_LESS_in_include131 = new BitSet(new long[]{0x2000000000000000L}); + public static final BitSet FOLLOW_61_in_include133 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_include135 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_LESS_in_main148 = new BitSet(new long[]{0x0000000000080000L}); + public static final BitSet FOLLOW_MODULE_in_main150 = new BitSet(new long[]{0x0000000000100000L}); + public static final BitSet FOLLOW_NAME_in_main152 = new BitSet(new long[]{0x0000000800000000L}); + public static final BitSet FOLLOW_EQUALS_in_main154 = new BitSet(new long[]{0x0000000000040000L}); + public static final BitSet FOLLOW_QUOTE_in_main156 = new BitSet(new long[]{0x4000000000000000L}); + public static final BitSet FOLLOW_62_in_main158 = new BitSet(new long[]{0x0000000000040000L}); + public static final BitSet FOLLOW_QUOTE_in_main160 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_main162 = new BitSet(new long[]{0x0000002000000020L}); + public static final BitSet FOLLOW_variables_in_main171 = new BitSet(new long[]{0x0000002000000020L}); + public static final BitSet FOLLOW_constants_in_main174 = new BitSet(new long[]{0x0000002000000020L}); + public static final BitSet FOLLOW_instantiation_in_main177 = new BitSet(new long[]{0x0000002000000000L}); + public static final BitSet FOLLOW_LESS_in_main179 = new BitSet(new long[]{0x8000000000000000L}); + public static final BitSet FOLLOW_63_in_main181 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_main183 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_LESS_in_process198 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000001L}); + public static final BitSet FOLLOW_64_in_process200 = new BitSet(new long[]{0x0000000000100000L}); + public static final BitSet FOLLOW_NAME_in_process202 = new BitSet(new long[]{0x0000000800000000L}); + public static final BitSet FOLLOW_EQUALS_in_process204 = new BitSet(new long[]{0x0000000000040000L}); + public static final BitSet FOLLOW_QUOTE_in_process206 = new BitSet(new long[]{0x0000000000000020L}); + public static final BitSet FOLLOW_ID_in_process210 = new BitSet(new long[]{0x0000000000040000L}); + public static final BitSet FOLLOW_QUOTE_in_process212 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_process214 = new BitSet(new long[]{0x0000002000000000L}); + public static final BitSet FOLLOW_LESS_in_process216 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000002L}); + public static final BitSet FOLLOW_65_in_process218 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_process220 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_LESS_in_moduleClass243 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000004L}); + public static final BitSet FOLLOW_66_in_moduleClass245 = new BitSet(new long[]{0x0000000000100000L}); + public static final BitSet FOLLOW_NAME_in_moduleClass247 = new BitSet(new long[]{0x0000000800000000L}); + public static final BitSet FOLLOW_EQUALS_in_moduleClass249 = new BitSet(new long[]{0x0000000000040000L}); + public static final BitSet FOLLOW_QUOTE_in_moduleClass251 = new BitSet(new long[]{0x0000000000000020L}); + public static final BitSet FOLLOW_ID_in_moduleClass255 = new BitSet(new long[]{0x0000000000040000L}); + public static final BitSet FOLLOW_QUOTE_in_moduleClass270 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000008L}); + public static final BitSet FOLLOW_67_in_moduleClass272 = new BitSet(new long[]{0x0000000800000000L}); + public static final BitSet FOLLOW_EQUALS_in_moduleClass274 = new BitSet(new long[]{0x0000000000040000L}); + public static final BitSet FOLLOW_QUOTE_in_moduleClass276 = new BitSet(new long[]{0x0000000000040020L}); + public static final BitSet FOLLOW_ID_in_moduleClass283 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000010L}); + public static final BitSet FOLLOW_68_in_moduleClass300 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_expression_in_moduleClass304 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000020L}); + public static final BitSet FOLLOW_69_in_moduleClass320 = new BitSet(new long[]{0x0000000000060000L,0x0000000000000010L}); + public static final BitSet FOLLOW_ID_in_moduleClass344 = new BitSet(new long[]{0x0000000000060000L}); + public static final BitSet FOLLOW_COMMA_in_moduleClass364 = new BitSet(new long[]{0x0000000000000020L}); + public static final BitSet FOLLOW_ID_in_moduleClass368 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000010L}); + public static final BitSet FOLLOW_68_in_moduleClass384 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_expression_in_moduleClass388 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000020L}); + public static final BitSet FOLLOW_69_in_moduleClass404 = new BitSet(new long[]{0x0000000000060000L,0x0000000000000010L}); + public static final BitSet FOLLOW_COMMA_in_moduleClass427 = new BitSet(new long[]{0x0000000000000020L}); + public static final BitSet FOLLOW_ID_in_moduleClass431 = new BitSet(new long[]{0x0000000000060000L}); + public static final BitSet FOLLOW_QUOTE_in_moduleClass454 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_moduleClass456 = new BitSet(new long[]{0x0000002000000000L}); + public static final BitSet FOLLOW_constants_in_moduleClass458 = new BitSet(new long[]{0x0000002000000000L}); + public static final BitSet FOLLOW_variables_in_moduleClass461 = new BitSet(new long[]{0x0000002000000000L}); + public static final BitSet FOLLOW_logic_in_moduleClass463 = new BitSet(new long[]{0x0000002000000000L}); + public static final BitSet FOLLOW_LESS_in_moduleClass465 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000040L}); + public static final BitSet FOLLOW_70_in_moduleClass467 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_moduleClass469 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_LESS_in_constants494 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000080L}); + public static final BitSet FOLLOW_71_in_constants496 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_constants498 = new BitSet(new long[]{0x0000002000000020L}); + public static final BitSet FOLLOW_ID_in_constants503 = new BitSet(new long[]{0x0000000800000000L}); + public static final BitSet FOLLOW_EQUALS_in_constants505 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_INT_in_constants509 = new BitSet(new long[]{0x0000000000004000L}); + public static final BitSet FOLLOW_SEMICOLON_in_constants520 = new BitSet(new long[]{0x0000002000000020L}); + public static final BitSet FOLLOW_LESS_in_constants524 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000100L}); + public static final BitSet FOLLOW_72_in_constants526 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_constants528 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_LESS_in_globalConstants545 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000080L}); + public static final BitSet FOLLOW_71_in_globalConstants547 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_globalConstants549 = new BitSet(new long[]{0x0000002000000020L}); + public static final BitSet FOLLOW_ID_in_globalConstants554 = new BitSet(new long[]{0x0000000800000000L}); + public static final BitSet FOLLOW_EQUALS_in_globalConstants556 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_INT_in_globalConstants560 = new BitSet(new long[]{0x0000000000004000L}); + public static final BitSet FOLLOW_SEMICOLON_in_globalConstants586 = new BitSet(new long[]{0x0000002000000020L}); + public static final BitSet FOLLOW_LESS_in_globalConstants590 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000100L}); + public static final BitSet FOLLOW_72_in_globalConstants592 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_globalConstants594 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_LESS_in_globalVariables608 = new BitSet(new long[]{0x0000000000800000L}); + public static final BitSet FOLLOW_INTERNAL_in_globalVariables610 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_globalVariables612 = new BitSet(new long[]{0x0000000000000020L}); + public static final BitSet FOLLOW_globalVarDecl_in_globalVariables615 = new BitSet(new long[]{0x0000002000000020L}); + public static final BitSet FOLLOW_globalArrayDecl_in_globalVariables619 = new BitSet(new long[]{0x0000002000000020L}); + public static final BitSet FOLLOW_LESS_in_globalVariables623 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000200L}); + public static final BitSet FOLLOW_73_in_globalVariables625 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_globalVariables627 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_ID_in_globalVarDecl640 = new BitSet(new long[]{0x0000000800000000L}); + public static final BitSet FOLLOW_EQUALS_in_globalVarDecl650 = new BitSet(new long[]{0x0000000000000060L}); + public static final BitSet FOLLOW_INT_in_globalVarDecl655 = new BitSet(new long[]{0x0000000000004000L}); + public static final BitSet FOLLOW_ID_in_globalVarDecl669 = new BitSet(new long[]{0x0000000000004000L}); + public static final BitSet FOLLOW_SEMICOLON_in_globalVarDecl680 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_ID_in_globalArrayDecl694 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000010L}); + public static final BitSet FOLLOW_68_in_globalArrayDecl704 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_expression_in_globalArrayDecl709 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000020L}); + public static final BitSet FOLLOW_69_in_globalArrayDecl721 = new BitSet(new long[]{0x0000000000004000L,0x0000000000000010L}); + public static final BitSet FOLLOW_SEMICOLON_in_globalArrayDecl725 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_LESS_in_variables741 = new BitSet(new long[]{0x0000000000800000L}); + public static final BitSet FOLLOW_INTERNAL_in_variables743 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_variables745 = new BitSet(new long[]{0x0000000000000020L}); + public static final BitSet FOLLOW_varDecl_in_variables749 = new BitSet(new long[]{0x0000002000000020L}); + public static final BitSet FOLLOW_arrayDecl_in_variables753 = new BitSet(new long[]{0x0000002000000020L}); + public static final BitSet FOLLOW_LESS_in_variables757 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000200L}); + public static final BitSet FOLLOW_73_in_variables759 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_variables761 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_ID_in_varDecl778 = new BitSet(new long[]{0x0000000800000000L}); + public static final BitSet FOLLOW_EQUALS_in_varDecl788 = new BitSet(new long[]{0x0000000000000060L}); + public static final BitSet FOLLOW_INT_in_varDecl793 = new BitSet(new long[]{0x0000000000004000L}); + public static final BitSet FOLLOW_ID_in_varDecl807 = new BitSet(new long[]{0x0000000000004000L}); + public static final BitSet FOLLOW_SEMICOLON_in_varDecl826 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_ID_in_arrayDecl840 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000010L}); + public static final BitSet FOLLOW_68_in_arrayDecl851 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_expression_in_arrayDecl856 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000020L}); + public static final BitSet FOLLOW_69_in_arrayDecl867 = new BitSet(new long[]{0x0000000800004000L,0x0000000000000010L}); + public static final BitSet FOLLOW_EQUALS_in_arrayDecl879 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000400L}); + public static final BitSet FOLLOW_74_in_arrayDecl889 = new BitSet(new long[]{0x0000000000000060L}); + public static final BitSet FOLLOW_INT_in_arrayDecl894 = new BitSet(new long[]{0x0000000000000060L,0x0000000000000800L}); + public static final BitSet FOLLOW_ID_in_arrayDecl908 = new BitSet(new long[]{0x0000000000000060L,0x0000000000000800L}); + public static final BitSet FOLLOW_75_in_arrayDecl920 = new BitSet(new long[]{0x0000000000004000L}); + public static final BitSet FOLLOW_SEMICOLON_in_arrayDecl932 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_ID_in_instantiation950 = new BitSet(new long[]{0x0000000000000020L}); + public static final BitSet FOLLOW_ID_in_instantiation954 = new BitSet(new long[]{0x0000000000000100L}); + public static final BitSet FOLLOW_LPAREN_in_instantiation970 = new BitSet(new long[]{0x0000000000000280L}); + public static final BitSet FOLLOW_MEMBER_in_instantiation975 = new BitSet(new long[]{0x0000000000020000L}); + public static final BitSet FOLLOW_COMMA_in_instantiation977 = new BitSet(new long[]{0x0000000000000080L}); + public static final BitSet FOLLOW_MEMBER_in_instantiation997 = new BitSet(new long[]{0x0000000000000200L}); + public static final BitSet FOLLOW_RPAREN_in_instantiation1015 = new BitSet(new long[]{0x0000000000004000L}); + public static final BitSet FOLLOW_SEMICOLON_in_instantiation1017 = new BitSet(new long[]{0x0000000000000022L}); + public static final BitSet FOLLOW_marking_in_logic1063 = new BitSet(new long[]{0x0000002000000000L}); + public static final BitSet FOLLOW_transition_in_logic1066 = new BitSet(new long[]{0x0000002000000002L}); + public static final BitSet FOLLOW_LESS_in_marking1119 = new BitSet(new long[]{0x0000000001000000L}); + public static final BitSet FOLLOW_MARKING_in_marking1121 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_marking1123 = new BitSet(new long[]{0x0000002000000060L}); + public static final BitSet FOLLOW_INT_in_marking1129 = new BitSet(new long[]{0x0000002000020000L}); + public static final BitSet FOLLOW_ID_in_marking1155 = new BitSet(new long[]{0x0000002000020000L}); + public static final BitSet FOLLOW_COMMA_in_marking1179 = new BitSet(new long[]{0x0000000000000060L}); + public static final BitSet FOLLOW_INT_in_marking1184 = new BitSet(new long[]{0x0000002000020000L}); + public static final BitSet FOLLOW_ID_in_marking1210 = new BitSet(new long[]{0x0000002000020000L}); + public static final BitSet FOLLOW_LESS_in_marking1237 = new BitSet(new long[]{0x0000000000000000L,0x0000000000001000L}); + public static final BitSet FOLLOW_76_in_marking1239 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_marking1241 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_LESS_in_transition1275 = new BitSet(new long[]{0x0000000004000000L}); + public static final BitSet FOLLOW_TRANSITION_in_transition1277 = new BitSet(new long[]{0x0000000008000000L}); + public static final BitSet FOLLOW_LABEL_in_transition1279 = new BitSet(new long[]{0x0000000800000000L}); + public static final BitSet FOLLOW_EQUALS_in_transition1281 = new BitSet(new long[]{0x0000000000040000L}); + public static final BitSet FOLLOW_QUOTE_in_transition1283 = new BitSet(new long[]{0x0000000000000060L}); + public static final BitSet FOLLOW_set_in_transition1287 = new BitSet(new long[]{0x0000000000040000L}); + public static final BitSet FOLLOW_QUOTE_in_transition1293 = new BitSet(new long[]{0x0000000010000000L}); + public static final BitSet FOLLOW_PRESET_in_transition1295 = new BitSet(new long[]{0x0000000800000000L}); + public static final BitSet FOLLOW_EQUALS_in_transition1297 = new BitSet(new long[]{0x0000000000040000L}); + public static final BitSet FOLLOW_QUOTE_in_transition1300 = new BitSet(new long[]{0x0000000000040000L}); + public static final BitSet FOLLOW_QUOTE_in_transition1302 = new BitSet(new long[]{0x0000000020000000L}); + public static final BitSet FOLLOW_QUOTE_in_transition1307 = new BitSet(new long[]{0x0000000000000060L}); + public static final BitSet FOLLOW_INT_in_transition1312 = new BitSet(new long[]{0x0000000000060000L}); + public static final BitSet FOLLOW_ID_in_transition1332 = new BitSet(new long[]{0x0000000000060000L}); + public static final BitSet FOLLOW_COMMA_in_transition1348 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_INT_in_transition1352 = new BitSet(new long[]{0x0000000000060000L}); + public static final BitSet FOLLOW_COMMA_in_transition1370 = new BitSet(new long[]{0x0000000000000020L}); + public static final BitSet FOLLOW_ID_in_transition1374 = new BitSet(new long[]{0x0000000000060000L}); + public static final BitSet FOLLOW_QUOTE_in_transition1389 = new BitSet(new long[]{0x0000000020000000L}); + public static final BitSet FOLLOW_POSTSET_in_transition1393 = new BitSet(new long[]{0x0000000800000000L}); + public static final BitSet FOLLOW_EQUALS_in_transition1395 = new BitSet(new long[]{0x0000000000040000L}); + public static final BitSet FOLLOW_QUOTE_in_transition1399 = new BitSet(new long[]{0x0000000000040000L}); + public static final BitSet FOLLOW_QUOTE_in_transition1401 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_QUOTE_in_transition1406 = new BitSet(new long[]{0x0000000000000060L}); + public static final BitSet FOLLOW_INT_in_transition1412 = new BitSet(new long[]{0x0000000000060000L}); + public static final BitSet FOLLOW_ID_in_transition1432 = new BitSet(new long[]{0x0000000000060000L}); + public static final BitSet FOLLOW_COMMA_in_transition1457 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_INT_in_transition1461 = new BitSet(new long[]{0x0000000000060000L}); + public static final BitSet FOLLOW_COMMA_in_transition1482 = new BitSet(new long[]{0x0000000000000020L}); + public static final BitSet FOLLOW_ID_in_transition1485 = new BitSet(new long[]{0x0000000000060000L}); + public static final BitSet FOLLOW_QUOTE_in_transition1504 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_transition1509 = new BitSet(new long[]{0x0000002000000020L,0x000000000001C000L}); + public static final BitSet FOLLOW_guard_in_transition1512 = new BitSet(new long[]{0x0000002000000020L,0x0000000000014000L}); + public static final BitSet FOLLOW_delay_in_transition1532 = new BitSet(new long[]{0x0000002000000020L,0x0000000000004000L}); + public static final BitSet FOLLOW_assertion_in_transition1553 = new BitSet(new long[]{0x0000002000000020L,0x0000000000004000L}); + public static final BitSet FOLLOW_assignment_in_transition1573 = new BitSet(new long[]{0x0000002000000020L,0x0000000000004000L}); + public static final BitSet FOLLOW_LESS_in_transition1593 = new BitSet(new long[]{0x0000000000000000L,0x0000000000002000L}); + public static final BitSet FOLLOW_77_in_transition1595 = new BitSet(new long[]{0x0000001000000000L}); + public static final BitSet FOLLOW_GREATER_in_transition1597 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_78_in_assertion1631 = new BitSet(new long[]{0x0000000000000100L}); + public static final BitSet FOLLOW_LPAREN_in_assertion1633 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_expression_in_assertion1635 = new BitSet(new long[]{0x0000000000000200L}); + public static final BitSet FOLLOW_RPAREN_in_assertion1637 = new BitSet(new long[]{0x0000000000004000L}); + public static final BitSet FOLLOW_SEMICOLON_in_assertion1639 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_79_in_guard1664 = new BitSet(new long[]{0x0000000000000100L}); + public static final BitSet FOLLOW_LPAREN_in_guard1666 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_expression_in_guard1668 = new BitSet(new long[]{0x0000000000000200L}); + public static final BitSet FOLLOW_RPAREN_in_guard1670 = new BitSet(new long[]{0x0000000000004000L}); + public static final BitSet FOLLOW_SEMICOLON_in_guard1672 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_80_in_delay1706 = new BitSet(new long[]{0x0000000000000100L}); + public static final BitSet FOLLOW_LPAREN_in_delay1708 = new BitSet(new long[]{0x0000000000000040L}); + public static final BitSet FOLLOW_INT_in_delay1712 = new BitSet(new long[]{0x0000000000020000L}); + public static final BitSet FOLLOW_COMMA_in_delay1726 = new BitSet(new long[]{0x0000000000000040L,0x0000000000020000L}); + public static final BitSet FOLLOW_INT_in_delay1731 = new BitSet(new long[]{0x0000000000000200L}); + public static final BitSet FOLLOW_81_in_delay1746 = new BitSet(new long[]{0x0000000000000200L}); + public static final BitSet FOLLOW_RPAREN_in_delay1759 = new BitSet(new long[]{0x0000000000004000L}); + public static final BitSet FOLLOW_SEMICOLON_in_delay1761 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_ID_in_assignment1787 = new BitSet(new long[]{0x0000000800000000L}); + public static final BitSet FOLLOW_EQUALS_in_assignment1789 = new BitSet(new long[]{0x0000000000000020L}); + public static final BitSet FOLLOW_ID_in_assignment1793 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_ID_in_assignment1815 = new BitSet(new long[]{0x0000000800000000L}); + public static final BitSet FOLLOW_EQUALS_in_assignment1817 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_expression_in_assignment1835 = new BitSet(new long[]{0x0000000000004000L}); + public static final BitSet FOLLOW_SEMICOLON_in_assignment1850 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_ID_in_assignment1858 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000010L}); + public static final BitSet FOLLOW_68_in_assignment1875 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_expression_in_assignment1880 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000020L}); + public static final BitSet FOLLOW_69_in_assignment1897 = new BitSet(new long[]{0x0000000800000000L,0x0000000000000010L}); + public static final BitSet FOLLOW_EQUALS_in_assignment1901 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_expression_in_assignment1905 = new BitSet(new long[]{0x0000000000004000L}); + public static final BitSet FOLLOW_SEMICOLON_in_assignment1920 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_ID_in_term1951 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_ID_in_term1970 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000010L}); + public static final BitSet FOLLOW_68_in_term1986 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_expression_in_term1991 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000020L}); + public static final BitSet FOLLOW_69_in_term2006 = new BitSet(new long[]{0x0000000000000002L,0x0000000000000010L}); + public static final BitSet FOLLOW_LPAREN_in_term2031 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_expression_in_term2033 = new BitSet(new long[]{0x0000000000000200L}); + public static final BitSet FOLLOW_RPAREN_in_term2035 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_INT_in_term2047 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_TRUE_in_term2059 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_FALSE_in_term2071 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_PLUS_in_unary2108 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_MINUS_in_unary2113 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_term_in_unary2120 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_BITWISE_NEGATION_in_bitwiseNegation2151 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_unary_in_bitwiseNegation2157 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_NEGATION_in_negation2183 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_bitwiseNegation_in_negation2189 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_negation_in_mult2217 = new BitSet(new long[]{0x0000000700000002L}); + public static final BitSet FOLLOW_TIMES_in_mult2229 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_negation_in_mult2233 = new BitSet(new long[]{0x0000000700000002L}); + public static final BitSet FOLLOW_DIV_in_mult2244 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_negation_in_mult2248 = new BitSet(new long[]{0x0000000700000002L}); + public static final BitSet FOLLOW_MOD_in_mult2259 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_negation_in_mult2263 = new BitSet(new long[]{0x0000000700000002L}); + public static final BitSet FOLLOW_mult_in_add2302 = new BitSet(new long[]{0x00000000C0000002L}); + public static final BitSet FOLLOW_PLUS_in_add2313 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_mult_in_add2317 = new BitSet(new long[]{0x00000000C0000002L}); + public static final BitSet FOLLOW_MINUS_in_add2329 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_mult_in_add2333 = new BitSet(new long[]{0x00000000C0000002L}); + public static final BitSet FOLLOW_add_in_shift2372 = new BitSet(new long[]{0x000C000000000002L}); + public static final BitSet FOLLOW_BITWISE_LSHIFT_in_shift2383 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_add_in_shift2387 = new BitSet(new long[]{0x000C000000000002L}); + public static final BitSet FOLLOW_BITWISE_RSHIFT_in_shift2399 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_add_in_shift2403 = new BitSet(new long[]{0x000C000000000002L}); + public static final BitSet FOLLOW_shift_in_relation2438 = new BitSet(new long[]{0x000000F000000002L}); + public static final BitSet FOLLOW_LESS_in_relation2449 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_shift_in_relation2453 = new BitSet(new long[]{0x000000F000000002L}); + public static final BitSet FOLLOW_LESS_EQUAL_in_relation2465 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_shift_in_relation2469 = new BitSet(new long[]{0x000000F000000002L}); + public static final BitSet FOLLOW_GREATER_EQUAL_in_relation2481 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_shift_in_relation2485 = new BitSet(new long[]{0x000000F000000002L}); + public static final BitSet FOLLOW_GREATER_in_relation2497 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_shift_in_relation2501 = new BitSet(new long[]{0x000000F000000002L}); + public static final BitSet FOLLOW_relation_in_equivalence2540 = new BitSet(new long[]{0x0000030000000002L}); + public static final BitSet FOLLOW_EQUIV_in_equivalence2551 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_relation_in_equivalence2555 = new BitSet(new long[]{0x0000030000000002L}); + public static final BitSet FOLLOW_NOT_EQUIV_in_equivalence2566 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_relation_in_equivalence2570 = new BitSet(new long[]{0x0000030000000002L}); + public static final BitSet FOLLOW_equivalence_in_bitwiseAnd2609 = new BitSet(new long[]{0x0000800000000002L}); + public static final BitSet FOLLOW_BITWISE_AND_in_bitwiseAnd2621 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_equivalence_in_bitwiseAnd2625 = new BitSet(new long[]{0x0000800000000002L}); + public static final BitSet FOLLOW_bitwiseAnd_in_bitwiseXor2664 = new BitSet(new long[]{0x0002000000000002L}); + public static final BitSet FOLLOW_BITWISE_XOR_in_bitwiseXor2675 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_bitwiseAnd_in_bitwiseXor2679 = new BitSet(new long[]{0x0002000000000002L}); + public static final BitSet FOLLOW_bitwiseXor_in_bitwiseOr2718 = new BitSet(new long[]{0x0001000000000002L}); + public static final BitSet FOLLOW_BITWISE_OR_in_bitwiseOr2729 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_bitwiseXor_in_bitwiseOr2733 = new BitSet(new long[]{0x0001000000000002L}); + public static final BitSet FOLLOW_bitwiseOr_in_and2772 = new BitSet(new long[]{0x0000080000000002L}); + public static final BitSet FOLLOW_AND_in_and2783 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_bitwiseOr_in_and2787 = new BitSet(new long[]{0x0000080000000002L}); + public static final BitSet FOLLOW_and_in_or2826 = new BitSet(new long[]{0x0000100000000002L}); + public static final BitSet FOLLOW_OR_in_or2837 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_and_in_or2841 = new BitSet(new long[]{0x0000100000000002L}); + public static final BitSet FOLLOW_or_in_implication2878 = new BitSet(new long[]{0x0000200000000002L}); + public static final BitSet FOLLOW_IMPLICATION_in_implication2889 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_or_in_implication2893 = new BitSet(new long[]{0x0000200000000002L}); + public static final BitSet FOLLOW_implication_in_expression2933 = new BitSet(new long[]{0x0000000000001002L}); + public static final BitSet FOLLOW_QMARK_in_expression2943 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_expression_in_expression2947 = new BitSet(new long[]{0x0000000000002000L}); + public static final BitSet FOLLOW_COLON_in_expression2949 = new BitSet(new long[]{0x00004400C0000D60L}); + public static final BitSet FOLLOW_expression_in_expression2953 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_ID_in_ctlTerm2989 = new BitSet(new long[]{0x0000000000000002L}); + public static final BitSet FOLLOW_LPAREN_in_ctlTerm2994 = new BitSet(new long[]{0x0000000000000100L}); + public static final BitSet FOLLOW_ctl_in_ctlTerm2996 = new BitSet(new long[]{0x0000000000000100L}); + public static final BitSet FOLLOW_LPAREN_in_ctlTerm2998 = new BitSet(new long[]{0x0000000000000002L}); + +} \ No newline at end of file diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/WriteLPN.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/WriteLPN.java new file mode 100644 index 000000000..a008e0846 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/platuLpn/io/WriteLPN.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ + +package edu.utah.ece.async.lema.verification.platu.platuLpn.io; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.*; + +import edu.utah.ece.async.lema.verification.platu.platuLpn.LPNTran; +import edu.utah.ece.async.lema.verification.platu.platuLpn.PlatuLPN; +import edu.utah.ece.async.lema.verification.platu.platuLpn.VarSet; +import edu.utah.ece.async.lema.verification.platu.platuLpn.VarVal; + +/** + * @author ldtwo + */ +public class WriteLPN { + + public static void write(String file, PlatuLPN[] lpnArr) throws Exception { + if (file == null || lpnArr == null) { + throw new NullPointerException(); + } + write(new File(file), lpnArr); + } + + public static void write(File file, PlatuLPN[] lpnArr) throws Exception { + if (file == null || lpnArr == null) { + throw new NullPointerException(); + } + if (!file.exists()) { + throw new FileNotFoundException(); + } + write(new FileOutputStream(file, true), lpnArr); + + } + + public static void write(FileOutputStream out, PlatuLPN[] lpnArr) throws Exception { + if (out == null || lpnArr == null) { + throw new NullPointerException(); + } + for (PlatuLPN lpn : lpnArr) { + write(out, lpn); + } + out.write((".end\n").getBytes()); + + } + + public static void write(String file, PlatuLPN lpn) throws Exception { + if (file == null || lpn == null) { + throw new NullPointerException(); + } + write(new File(file), lpn); + } + + public static void write(File file, PlatuLPN lpn) throws Exception { + if (file == null || lpn == null) { + throw new NullPointerException(); + } + write(new FileOutputStream(file, true) { + + @Override + public void write(byte[] b) throws IOException { + super.write(b); + debugPrint(">>" + new String(b).replace("\n", "\\n")); + } + }, lpn); + } +static final Comparator vvComparator=new Comparator() { + + @Override + public int compare(VarVal o1, VarVal o2) { + return o1.getVariable().compareTo(o2.getVariable()); + } + }; + + public static void write(FileOutputStream out, PlatuLPN lpn) throws Exception { + if (out == null || lpn == null) { + throw new NullPointerException(); + } + //lines 1..4 + debugPrint("writting..."); + out.write((".module " + lpn.getLabel() + "\n").getBytes()); + String[] varLbl = {"INPUTS: ", "OUTPUTS: ", "INTERNALS: "}; + + VarSet vvi = lpn.getInputs(); + debugPrint("vvi.size=" + vvi.size()); + VarSet vvo = lpn.getOutputs(); + debugPrint("vvo.size=" + vvi.size()); + VarSet vvn = lpn.getInternals(); + debugPrint("vvn.size=" + vvi.size()); + + + String[][] tmp; + tmp = new String[][]{//inputs, outputs, internals + vvi.size() == 0 ? new String[0] : vvi.toArray(new String[]{}), + vvo.size() == 0 ? new String[0] : vvo.toArray(new String[]{}), + vvn.size() == 0 ? new String[0] : vvn.toArray(new String[]{}) + }; + Arrays.sort(tmp[0]); + Arrays.sort(tmp[1]); + Arrays.sort(tmp[2]); + + for (int y = 0; y < 3; y++) { + out.write((varLbl[y]).getBytes()); + if (tmp[y] == null) { + new NullPointerException().printStackTrace(); + } + if (tmp[y].length > 0) { + for (int x = 0; x < tmp[y].length - 1; x++) { + if (tmp[y][x] == null) { + new NullPointerException().printStackTrace(); + } + out.write((tmp[y][x] + ", \n\t").getBytes()); + } + out.write((tmp[y][tmp[y].length - 1] + ";\n").getBytes()); + } else { + out.write(("\n").getBytes()); + } + } + //line 5 + out.write(("{").getBytes()); + + List tmp1 = new ArrayList(); +// for(int i = 0; i < lpn.getInitStateTimed().getMarking().length; i++) +// tmp1.add(lpn.getInitStateTimed().getMarking()[i]); + Iterator it = tmp1.iterator(); + + // debugPrint("MARK>>"); + while (it.hasNext()) { + out.write((it.next() + "").getBytes()); + if (it.hasNext()) { + out.write((", ").getBytes()); + } + } + out.write(("};\n{").getBytes()); + int i = 0; + + out.write(("};\n").getBytes()); + LPNTran[] transitions=lpn.getTransitions().toArray(new LPNTran[0]); + Comparator comp=new Comparator() { + + @Override + public int compare(LPNTran o1, LPNTran o2) { + return o1.getIndex()>o2.getIndex()?1:-1; + } + }; + Arrays.sort(transitions, comp); +// Iterator it3 = lpn.getTransitions().iterator(); +// LPNTran tranTmp; + //debugPrint("TRANS>>"); + i=0; + String[] tranArray=new String[lpn.getTransitions().size()]; + for(LPNTran t:transitions) { + tranArray[i++]=t.toString(); + } +// Arrays.sort(tranArray); + for(String tran:tranArray){ + out.write((tran).getBytes()); + } + out.write("\n.end".getBytes()); + } + + private static void debugPrint(Object o) { + // System.out.println(o); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/AmpleSet.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/AmpleSet.java new file mode 100644 index 000000000..a142859d1 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/AmpleSet.java @@ -0,0 +1,363 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.por1; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; + +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LPNTranRelation; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LpnTranList; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class AmpleSet { + + private HashSet allInterleavingTrans = new HashSet(); + private HashMap> interleavingSet = new HashMap>(); + private HashMap> indepTranSet = new HashMap>(); + + public HashMap> getIndepTranSet_FromState(StateGraph[] lpnList, + LPNTranRelation lpnTranRelation) + { + SearchDepFromState sg = new SearchDepFromState(lpnList,lpnTranRelation); + indepTranSet = sg.getIndepTranSet(); + allInterleavingTrans = sg.getInterleavingTrans(); + interleavingSet = sg.getInterleavingSet(); + return indepTranSet; + } + + public HashMap> getIndepTranSet_FromLPN(StateGraph[] lpnList) + { + SearchDepFromLPN sg = new SearchDepFromLPN(); + sg.setIndep(lpnList); + indepTranSet = sg.getIndepSet(); + allInterleavingTrans = sg.getAllInterleavingTrans(); + interleavingSet = sg.getInterleavingSet(); + return indepTranSet; + } + + public LpnTranList generateAmpleTranSet(LinkedList[] enabledArray, + HashMap> allIndepSet) + { + LpnTranList ampleSet = new LpnTranList(); + LpnTranList enableTranSet = AmpleSet.getEnableTranSet(enabledArray); + if(enableTranSet.size()==0) + { + System.out.println("there is no enable transition need to be fired!"); + ampleSet = enableTranSet; + } + else + { + //if there exist independent transition + if(allIndepSet == null || allIndepSet.size() == 0) + ampleSet = enableTranSet; + else + { + LpnTranList interleavingEnabledSet = AmpleSet.getInterleavingEnabledSet(enableTranSet, allInterleavingTrans); + + if(interleavingEnabledSet.size() == 0) //only consider set1 and set2 + ampleSet = AmpleSet.getSubset_noInterleaving(enableTranSet, allIndepSet); + else //partition enable transition to three part:(1)interleaving_pair(2)interleaving(3)set1 and set2 + ampleSet = AmpleSet.getSubset_withInterleaving1(interleavingEnabledSet, enableTranSet, allIndepSet,this.interleavingSet); + + } + } + return ampleSet; + } + + public LpnTranList generateAmpleTranSet(LpnTranList enableTranSet,HashMap> allIndepSet) + { + LpnTranList ampleSet = new LpnTranList(); + if(enableTranSet.size()==0) + { + System.out.println("there is no enable transition need to be fired!"); + ampleSet = enableTranSet; + } + else + { + //if there exist independent transition + if(allIndepSet == null || allIndepSet.size() == 0) + ampleSet = enableTranSet; + else + { + LpnTranList interleavingEnabledSet = AmpleSet.getInterleavingEnabledSet(enableTranSet, allInterleavingTrans); + + if(interleavingEnabledSet.size() == 0) //only consider set1 and set2 + ampleSet = AmpleSet.getSubset_noInterleaving(enableTranSet, allIndepSet); + else //partition enable transition to three part:(1)interleaving_pair(2)interleaving(3)set1 and set2 + ampleSet = AmpleSet.getSubset_withInterleaving1(interleavingEnabledSet, enableTranSet, allIndepSet,this.interleavingSet); + + } + } + return ampleSet; + } + /** + * if the enabledSet has no interleaving transition, + * we partition this enableSet to two independent subset and choose the small one. + * @param enabledList + * @param indepTranSet + * @return + */ + private static LpnTranList getSubset_noInterleaving(LpnTranList enableTranSet, + HashMap> indepTranSet) + { + LpnTranList set1 = new LpnTranList(); + LpnTranList set2 = new LpnTranList(); + + //partition set1 and set2 + for(Transition tran : enableTranSet) + { + if(set1.isEmpty()) + set1.add(tran); + else + { + HashSet indep_tran = indepTranSet.get(tran); + if(indep_tran == null) + set1.add(tran); + else + { + boolean dep_flag = false; + for(Transition t : set1) + { + if(!indep_tran.contains(t)) + { + dep_flag = true; + break; + } + } + if(dep_flag) + set1.add(tran); + else + set2.add(tran); + } + } + } + + //set subset + if(set1.size() > set2.size() && set2.size() != 0) + return set2; + return set1; + } + + + /** + * partition to 3 part: + * (1)interleaving transitions, do not consider dependent transitions + * (2) set1 and set2 + * @param interleavingEnabledSet + * @param remainEnabledList + * @param indepTranSet + * @return + */ + private static LpnTranList getSubset_withInterleaving1(LpnTranList interleavingEnabledSet, + LpnTranList enableTranSet, + HashMap> indepTranSet, + HashMap> interleavingSet) + { + LpnTranList subset = new LpnTranList(); + LpnTranList set1 = new LpnTranList(); + LpnTranList set2 = new LpnTranList(); + + //partition to 3 part + for(Transition tran : enableTranSet) + { + if(interleavingEnabledSet.contains(tran)) + continue; + + if(set1.isEmpty()) + set1.add(tran); + else + { + HashSet indep_tran = indepTranSet.get(tran); + if(indep_tran == null) + set1.add(tran); + else + { + boolean dep_flag = false; + for(Transition t : set1) + { + if(!indep_tran.contains(t)) + { + dep_flag = true; + break; + } + } + if(dep_flag) + set1.add(tran); + else + set2.add(tran); + } + } + } + + //choose independent subset + if(!set1.isEmpty() || !set2.isEmpty()) + { + //set subset + if(set1.size() > set2.size() && set2.size() != 0) + subset = set2; + else + subset = set1; + } + else//indep is empty + { + //System.out.println("there is no independent transition"); +// for(Transition tran : interleavingEnabledSet) +// set1.add(tran); +// return set1; + subset = AmpleSet.subset_indepIsEmpty(interleavingEnabledSet, interleavingSet, indepTranSet); + } + return subset; + } +/** + * all transitions are interleaving transition + * @param interleavingEnabledSet + * @param interleavingSet + * @param allIndepSet + * @return + */ + private static LpnTranList subset_indepIsEmpty(LpnTranList interleavingEnabledSet, + HashMap> interleavingSet, + HashMap> allIndepSet) + { + + LpnTranList ready_interleaving = new LpnTranList(); + + // if there exist interleaving pair + for(Transition tran1 : interleavingEnabledSet) + { + HashSet inter_setTran1 = interleavingSet.get(tran1); + boolean noExist = false; + //System.out.println("inter_setTran1.size():"+inter_setTran1.size()); + for(Transition inter : inter_setTran1) + { + if(!interleavingEnabledSet.contains(inter)) + { + noExist = true;break; + } + } + //interleaving pair exist, can be fire first + if(!noExist) + { + ready_interleaving.add(tran1); + for(Transition inter : inter_setTran1) + ready_interleaving.add(inter); + break; + } + } + /* + System.out.print("ready_interleaving:"); + for(Transition trans : ready_interleaving) + System.out.print(trans.getFullLabel()+","); + System.out.println(); + */ + if(!ready_interleaving.isEmpty()) + { + //System.out.println("there exists interleaving pairs ready to fire!"); + return ready_interleaving; + } + //System.out.println("choose all of the interleaving transitions which are independent with others"); + return interleavingEnabledSet; + //return this.getSubsetOfInterleavingTrans(interleavingEnabledSet); + + } + + + /** + * if there does not exist ready_interleaving, + * get subset of the interleaving + * @param interleavingEnabledSet + * @return + */ + @SuppressWarnings("unused") + private LpnTranList getSubsetOfInterleavingTrans(LpnTranList interleavingEnabledSet) + { + LpnTranList set1 = new LpnTranList(); + LpnTranList set2 = new LpnTranList(); + for(Transition tran : interleavingEnabledSet) + { + if(set1.isEmpty()) + set1.add(tran); + else + { + boolean interleaving = false; + for(Transition setTran : set1) + { + HashSet inter_setTran = interleavingSet.get(setTran); + if(inter_setTran.contains(tran)) + { + interleaving = true; + break; + } + } + if(interleaving == true) + set1.add(tran); + else + set2.add(tran); + } + } + + if(set1.size() > set2.size() && set2.size() != 0) + return set2; + return set1; + } + + /** + * get the interleaving transitions from the enable set + * @param enabledList + * @param interleavingSet + * @return + */ + private static LpnTranList getInterleavingEnabledSet(LpnTranList enableTranSet, HashSet interleavingSet) + { + LpnTranList interleavingEnabledSet = new LpnTranList(); + //System.out.println("interleavingSet.size():"+interleavingSet.size()); + if(interleavingSet != null) + { + for(Transition tran : enableTranSet) + { + if(interleavingSet.contains(tran)) + interleavingEnabledSet.add(tran); + } + } + return interleavingEnabledSet; + } + + private static LpnTranList getEnableTranSet(LinkedList[] enabledList) + { + LpnTranList enableTranSet = new LpnTranList(); + for (int index = 0; index < enabledList.length; index++) + { + //System.out.println("index:"+index); + if(enabledList[index].size()!=0) + { + for(Transition t: enabledList[index]) + enableTranSet.add(t); + } + } + //System.out.println("enableTranSet.size():"+enableTranSet.size()); + return enableTranSet; + } + + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/AmpleSubset.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/AmpleSubset.java new file mode 100644 index 000000000..33b2d17ec --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/AmpleSubset.java @@ -0,0 +1,538 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.por1; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; + +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LPNTranRelation; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LpnTranList; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class AmpleSubset { + + private HashSet allInterleavingTrans = new HashSet(); + private HashMap> interleavingSet = new HashMap>(); + + public HashMap> getIndepTranSet_FromState(StateGraph[] lpnList, + LPNTranRelation lpnTranRelation) + { + HashMap> indepTranSet = new HashMap>(); + SearchDepFromState sg = new SearchDepFromState(lpnList,lpnTranRelation); + indepTranSet = sg.getIndepTranSet(); + allInterleavingTrans = sg.getInterleavingTrans(); + interleavingSet = sg.getInterleavingSet(); + return indepTranSet; + } + + public HashMap> getIndepTranSet_FromLPN(StateGraph[] lpnList) + { + HashMap> indepTranSet = new HashMap>(); + SearchDepFromLPN sg = new SearchDepFromLPN(); + sg.setIndep(lpnList); + indepTranSet = sg.getIndepSet(); + allInterleavingTrans = sg.getAllInterleavingTrans(); + interleavingSet = sg.getInterleavingSet(); + return indepTranSet; + } + + + + /**(POR) + * reduce enableList to ampleList + * @param stateVisited + * @param enabledArray + * @param allIndepSet + * @param lpnList + * @return + */ + public LpnTranList generateAmpleList(boolean stateVisited, + LinkedList[] enabledArray, + HashMap> allIndepSet) + { + LpnTranList ampleList = new LpnTranList(); + LpnTranList enableTranSet = AmpleSubset.getEnableTranSet(enabledArray); + + if(enableTranSet.size()==0) + { + System.out.println("no enable transition,deadlock!"); + ampleList = enableTranSet; + } + else if(enableTranSet.size()==1) + { + ampleList = enableTranSet; + } + else + { + //cycle + if(stateVisited == true) + { + ampleList = enableTranSet; + return ampleList; + } + //exist independent transition + if(allIndepSet == null || allIndepSet.size() == 0) + ampleList = enableTranSet; + else + { + LpnTranList interleavingEnabledSet = AmpleSubset.getInterleavingEnabledSet(enableTranSet, allInterleavingTrans); + //System.out.println("interleavingEnabledSet.size():"+interleavingEnabledSet.size()); + + if(interleavingEnabledSet.size() == 0) //only consider set1 and set2 + { + ampleList = AmpleSubset.getSubset_noInterleaving(enabledArray, allIndepSet); + //System.out.println("ampleList.size():"+ampleList.size()); + return ampleList; + } + /* + System.out.print("interleaving trans:"); + for(LPNTran tran : interleavingEnabledSet) + { + System.out.print(tran.getFullLabel()+","); + } + System.out.println(); + */ + ampleList = AmpleSubset.getSubset_withInterleaving(interleavingEnabledSet, enabledArray, allIndepSet); + return ampleList; + } + } + + return ampleList; + } + + /** + * get the interleaving transitions from the enable set + * @param enabledList + * @param interleavingSet + * @return + */ + private static LpnTranList getInterleavingEnabledSet(LpnTranList enableTranSet, HashSet interleavingSet) + { + LpnTranList interleavingEnabledSet = new LpnTranList(); + //System.out.println("interleavingSet.size():"+interleavingSet.size()); + if(interleavingSet != null) + { + for(Transition tran : enableTranSet) + { + if(interleavingSet.contains(tran)) + interleavingEnabledSet.add(tran); + } + } + return interleavingEnabledSet; + } +/* + private LPNTranSet getInterleavingEnabledSet(LinkedList[] remainEnabledList, + HashSet interleavingSet) + { + LPNTranSet interleavingEnabledSet = null; + for (int index = 0; index < remainEnabledList.length; index++) + { + if(!remainEnabledList[index].isEmpty()) + { + LinkedList enableSet = remainEnabledList[index]; + + for(LPNTran t: enableSet) + { + if(interleavingSet.contains(t)) + { + if(interleavingEnabledSet==null) + interleavingEnabledSet = new LPNTranSet(); + interleavingEnabledSet.add(t); + remainEnabledList[index].remove(t); + } + } + } + } + return interleavingEnabledSet; + } +*/ + /** + * if the enabledSet has no interleaving transition, + * we partition this enableSet to two independent subset and choose the small one. + * @param enabledList + * @param indepTranSet + * @return + */ + private static LpnTranList getSubset_noInterleaving(LinkedList[] enabledList, + HashMap> indepTranSet) + { + LpnTranList set1 = new LpnTranList(); + LpnTranList set2 = new LpnTranList(); + //order + if(enabledList.length>1) + AmpleSubset.order(enabledList); + //partition set1 and set2 + for(int i=0;i<=enabledList.length-1;i++) + { + for(Transition tran : enabledList[i]) + { + if(set1.isEmpty()) + set1.add(tran); + else + { + HashSet indep_tran = indepTranSet.get(tran); + if(indep_tran == null) + set1.add(tran); + else + { + boolean dep_flag = false; + for(Transition t : set1) + { + if(!indep_tran.contains(t)) + { + dep_flag = true; + break; + } + } + if(dep_flag) + set1.add(tran); + else + set2.add(tran); + } + } + } + } + /* + System.out.print("Set1: "); + for(LPNTran tran: set1) + { + System.out.print(tran.getFullLabel()+","); + } + System.out.println(); + System.out.print("Set2: "); + for(LPNTran tran: set2) + { + System.out.print(tran.getFullLabel()+","); + } + System.out.println(); + */ + //set subset + if(set1.size() > set2.size() && set2.size() != 0) + return set2; + return set1; + } +/** + * partition to 3 part: + * (1)transition t1 dependent with interleaving and transition t2 dependent with t1 + * (2) set1 and set2 + * @param interleavingEnabledSet + * @param indepTranSet + * @param remainEnabledList + * @return + */ + private static LpnTranList getSubset_withInterleaving(LpnTranList interleavingEnabledSet, + LinkedList[] enabledList, + HashMap> indepTranSet) + { + LpnTranList subset = new LpnTranList(); + LpnTranList dep_interleaving = new LpnTranList(); + LpnTranList set1 = new LpnTranList(); + LpnTranList set2 = new LpnTranList(); + //order + if(enabledList.length>1) + AmpleSubset.order(enabledList); + //partition to 3 part + for(int i=0;i<=enabledList.length-1;i++) + { + for(Transition tran : enabledList[i]) + { + if(interleavingEnabledSet.contains(tran)) + continue; + + HashSet indep_tran = indepTranSet.get(tran); + if(indep_tran == null) + dep_interleaving.add(tran); + else + { + boolean dep_interleavingTR = false; + for(Transition interleaveTran : interleavingEnabledSet) + { + if(!indep_tran.contains(interleaveTran)) + { + dep_interleavingTR = true; + dep_interleaving.add(tran); + break; + } + } + //indep with interleaving. (1)consider indep with depset(2)consider set1 and set2 + if(dep_interleavingTR == false) + { + boolean dep_dep = false; + if(!dep_interleaving.isEmpty()) + { + for(Transition depTran : dep_interleaving) + { + if(!indep_tran.contains(depTran)) + { + dep_dep = true; + dep_interleaving.add(depTran); + break; + } + } + } + //indep with dep_transition set ,consider set1 and set2 + if(dep_dep == false) + { + if(set1.isEmpty()) + set1.add(tran); + else + { + boolean dep_flag = false; + for(Transition t : set1) + { + if(!indep_tran.contains(t)) + { + dep_flag = true; + break; + } + } + if(dep_flag) + set1.add(tran); + else + set2.add(tran); + } + } + } + } + } + } + //choose independent subset + if(!set1.isEmpty() || !set2.isEmpty()) + { + //set subset + if(set1.size() > set2.size() && set2.size() != 0) + subset = set2; + else + subset = set1; + } + else//indep is empty + { + + for(Transition tran : interleavingEnabledSet) + set1.add(tran); + for(Transition tran : dep_interleaving) + set1.add(tran); + return set1; + + //return this.subset_indepIsEmpty(interleavingEnabledSet, interleavingSet, dep_interleaving,indepTranSet); + } + return subset; + } + + @SuppressWarnings("unused") + private LpnTranList subset_indepIsEmpty(LpnTranList interleavingEnabledSet, + HashMap> interleavingSet, + LpnTranList dep_interleaving, + HashMap> allIndepSet) + { + LpnTranList ready_interleaving = new LpnTranList(); + + // if there exist interleaving pair + for(Transition tran1 : interleavingEnabledSet) + { + HashSet inter_setTran1 = interleavingSet.get(tran1); + boolean existNotContain = false; + for(Transition inter : inter_setTran1) + { + if(!interleavingEnabledSet.contains(inter)) + { + existNotContain = true;break; + } + } + //interleaving pair exist, can be fire first + if(!existNotContain) + { + ready_interleaving.add(tran1); + for(Transition inter : inter_setTran1) + ready_interleaving.add(inter); + } + } + + if(!ready_interleaving.isEmpty()) + { + if(!dep_interleaving.isEmpty()) + { + LpnTranList dep = AmpleSubset.getDepOfInterleavingTrans(ready_interleaving, dep_interleaving, allIndepSet); + for(Transition tran : dep) + ready_interleaving.add(tran); + } + return ready_interleaving; + } + LpnTranList subset = this.getSubsetOfInterleavingTrans(interleavingEnabledSet); + if(!dep_interleaving.isEmpty()) + { + LpnTranList dep = AmpleSubset.getDepOfInterleavingTrans(subset, dep_interleaving, allIndepSet); + for(Transition tran : dep) + subset.add(tran); + } + return subset; + } + /** + * if there does not exist ready_interleaving, + * get subset of the interleaving + * @param interleavingEnabledSet + * @return + */ + private LpnTranList getSubsetOfInterleavingTrans(LpnTranList interleavingEnabledSet) + { + LpnTranList set1 = new LpnTranList(); + LpnTranList set2 = new LpnTranList(); + for(Transition tran : interleavingEnabledSet) + { + if(set1.isEmpty()) + set1.add(tran); + else + { + boolean contain = false; + for(Transition setTran : set1) + { + HashSet inter_setTran = interleavingSet.get(setTran); + if(inter_setTran.contains(tran)) + { + contain = true; + break; + } + } + if(contain == true) + set1.add(tran); + else + set2.add(tran); + } + } + + if(set1.size() > set2.size() && set2.size() != 0) + return set2; + return set1; + } + + /** + * get the dependent transitions of the enableInterleaving transitions + * @param subInterleavingSet + * @param dep_interleaving + * @param allIndepSet + * @return + */ + private static LpnTranList getDepOfInterleavingTrans(LpnTranList subInterleavingSet, LpnTranList dep_interleaving, + HashMap> allIndepSet) + { + //dependent on interleaving + LpnTranList dep_sub = new LpnTranList(); + for(Transition tran : dep_interleaving) + { + HashSet indep_tran = allIndepSet.get(tran); + for(Transition tran_inter : subInterleavingSet) + { + if(!indep_tran.contains(tran_inter)) + { + dep_sub.add(tran);break; + } + } + } + //dependent on dep_interleaving + LpnTranList dep_dep = new LpnTranList(); + for(Transition tran : dep_interleaving) + { + if(!dep_sub.contains(tran)) + { + HashSet indep_tran = allIndepSet.get(tran); + for(Transition tran_dep : dep_sub) + { + if(!indep_tran.contains(tran_dep)) + { + dep_dep.add(tran);break; + } + } + } + } + + for(Transition dep : dep_dep) + { + dep_sub.add(dep); + } + return dep_sub; + } + + /** + * order the enabledList: the smallest the first + * @param enabledList + */ + private static void order(LinkedList[] enabledList) + { + LinkedList temp = new LinkedList(); + for(int i=0;ienabledList[j].size()) + { + temp = enabledList[j]; + enabledList[j] = enabledList[i]; + enabledList[i] = temp; + } + } + } + } + + private static LpnTranList getEnableTranSet(LinkedList[] enabledList) + { + LpnTranList enableTranSet = new LpnTranList(); + for (int index = 0; index < enabledList.length; index++) + { + //System.out.println("index:"+index); + if(enabledList[index].size()!=0) + { + for(Transition t: enabledList[index]) + enableTranSet.add(t); + } + } + //System.out.println("enableTranSet.size():"+enableTranSet.size()); + return enableTranSet; + } + + public static void printMap(HashMap> tranSet) + { + long number = 0; + Iterator it = tranSet.keySet().iterator(); + if(!it.hasNext()) + { + System.out.println("this transition type is null"); + } + while(it.hasNext()) + { + Transition key = it.next(); + HashSet value = tranSet.get(key); + System.out.print(key.getFullLabel()+" " ); + Iterator bb = value.iterator(); + while(bb.hasNext()) + { + number++; + System.out.print(bb.next().getFullLabel()+","); + } + System.out.println(); + } + System.out.println("number"+number); + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/SearchDepFromLPN.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/SearchDepFromLPN.java new file mode 100644 index 000000000..ea85cfeb1 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/SearchDepFromLPN.java @@ -0,0 +1,377 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.por1; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +/** + * in this approach, we consider 7 conditions for dependent transition + * Separate the interleaving transition and dependent transition. + * @author Administrator + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class SearchDepFromLPN { + + private HashMap> indepTranSet = new HashMap>(); + private HashMap> interleavingSet = new HashMap>(); + private HashSet interleavingTrans = new HashSet(); + + public HashMap> getIndepSet() + { + return this.indepTranSet; + } + public HashSet getAllInterleavingTrans() + { + return this.interleavingTrans; + } + public HashMap> getInterleavingSet() + { + return this.interleavingSet; + } + + public void setIndep(StateGraph[] lpnList) + { + // TODO: (future) change to use our LPN transitions + int number = 0; + /* + for(StateGraph sg : lpnList) + number = number + sg.getLpn().getTransitions().size(); + */ + Transition[] wholeSet = new Transition[number]; + /* + int i=0; + for(StateGraph sg : lpnList) + { + for(Transition tran : sg.getLpn().getTransitions()) + { + wholeSet[i] = tran; + i++; + } + } + */ + //System.out.println("wholeSet.size():"+wholeSet.length + " i : "+i); + + for(int t1=0;t1> LPNTransSet) + { + HashSet t1_dep = LPNTransSet.get(t1); + if(t1_dep == null) + { + t1_dep = new HashSet(); + LPNTransSet.put(t1, t1_dep); + } + t1_dep.add(t2); + + HashSet t2_dep = LPNTransSet.get(t2); + if(t2_dep == null) + { + t2_dep = new HashSet(); + LPNTransSet.put(t2, t2_dep); + } + t2_dep.add(t1); + } + /** + * flag 0 : represent independent + * flag 1: represent causality + * flag 2: represent interleaving + * @param t1 + * @param t2 + * @param wholeSet + * @return + */ + private static int checkDep(Transition t1, Transition t2, Transition[] wholeSet) + { + int flag = 0; + //in same LPN + if(t1.getLpn().getLabel().equals(t2.getLpn().getLabel()) ) + { + if(SearchDepFromLPN.ConditionCommonPreset(t1, t2)) + { + flag = 2; + //System.out.println("condition 1:"+ t1.getFullLabel()+ " same preset, interleaving "+t2.getFullLabel()); + return flag; + } + else if(SearchDepFromLPN.ConditionPrePost(t1, t2) || SearchDepFromLPN.ConditionPrePost(t2, t1)) + { + flag = 1; + //System.out.println("condition 2,3:"+ t1.getFullLabel()+ " pre-post,calsality "+t2.getFullLabel()); + return flag; + } + + } + //change + if(SearchDepFromLPN.ConditionSameAssignVar(t1, t2)) + { + flag = 2; + //System.out.println("condition 4:"+t1.getFullLabel()+ " same assign, interleaving "+t2.getFullLabel()); + } + //change + else if(SearchDepFromLPN.ConditionSuppAssign(t1, t2) || SearchDepFromLPN.ConditionSuppAssign(t2, t1)) + { + flag = 1; + //System.out.println("condition 5,6:"+t1.getFullLabel()+ " supp assign calsality "+t2.getFullLabel());//???????? + } + //change + else if(SearchDepFromLPN.ConditionChangeThirdTrans(t1, t2, wholeSet)) + { + flag = 2; + //System.out.println("condition 7:"+t1.getFullLabel()+ " third transition interleaving "+t2.getFullLabel()); + } + /* + else + { + System.out.println(t1.getFullLabel()+ " independent "+t2.getFullLabel()); + } + */ + return flag; + } + + /**Condition 1 + * check if these two transition has common preset + * @param t1 + * @param t2 + * @return + */ + private static boolean ConditionCommonPreset(Transition t1, Transition t2) + { + boolean flag = false; + // TODO: (future) Hack here. Created tmp to get rid of all errors + // TODO: must cut because NULL + /* + int[] tmp = null; + for(int i : tmp)//t1.getPreSet()) + { + for(int j: tmp) //t2.getPreSet()) + { + if(i==j) + { + flag = true; + break; + } + } + if(flag==true) + break; + } + */ + return flag; + } + + /**Condition 2 and 3 + * t1 -> t2 + * @param t1 + * @param t2 + * @return + */ + private static boolean ConditionPrePost(Transition t1, Transition t2) + { + boolean flag = false; + // TODO: (future) Hack here. Created tmp to get rid of all errors + // TODO: Must cut below because NULL + /* + int[] tmp = null; + for(int i : tmp)//t2.getPreSet()) + { + *//* + if(t1.getPostSet().contains(i)) + { + flag = true; + break; + } + *//* + } + */ + return flag; + } + /**Condition 4 + * check if two transition change the same variable + * @param t1 + * @param t2 + * @return + */ + private static boolean ConditionSameAssignVar(Transition t1, Transition t2) + { + boolean flag = false; + // TODO: (future) Hack here. Created tmp to get rid of all errors + // TODO: must cut because null + /* + VarNode[] tmp = null; + for(VarNode var1 : tmp)//t1.getAssignedVar()) + { + for(VarNode var2 : tmp) // t2.getAssignedVar()) + { + if(var2.getName() == var1.getName()) + { + flag = true; + break; + } + } + if(flag==true) + break; + } + */ + return flag; + } + /**Condition 5 and 6 + * t1 effect t2 + * @param t1 + * @param t2 + * @return + */ + private static boolean ConditionSuppAssign(Transition t1, Transition t2) + { + boolean flag = false; + // TODO: (future) Hack here. Created tmp to get rid of all errors + // TODO: must cut because NULL + /* + VarNode[] tmp = null; + for(VarNode var1 : tmp)//t1.getAssignedVar()) + { + *//* + if(t2.getSupportVar().contains(var1.getName())) + { + flag = true;break; + } + *//* + } + */ + return flag; + } + /**Condition 7 + * if two transition all change third transition's support variable, then + * these two transition need to be consider as interleaving. + * @param t1 + * @param t2 + * @param set + * @return + */ + private static boolean ConditionChangeThirdTrans(Transition t1, Transition t2, Transition[] wholeSet) + { + boolean flag = false; + for(Transition t3 : wholeSet) + { + if(t3 != t1 && t3 != t2) + { + boolean flag_1 = false; + boolean flag_2 = false; + // TODO: (future) Hack here. Created tmp to get rid of all errors + // TODO: must cut because NULL +// VarNode[] tmp = null; +// for(VarNode var : tmp)//t1.getAssignedVar()) +// { +// /* +// if(t3.getSupportVar().contains(var.getName())) +// { +// flag_1 = true;break; +// } +// */ +// } +// for(VarNode var : tmp) //t2.getAssignedVar()) +// { +// /* +// if(t3.getSupportVar().contains(var.getName())) +// { +// flag_2 = true;break; +// } +// */ +// } + if(flag_1 == true && flag_2 == true) + { + flag = true; + //System.out.println("third : "+ t3.getFullLabel()); + break; + } + } + } + return flag; + } + + private void setInterleavingTrans(HashMap> interleavingSet) + { + Iterator in = interleavingSet.entrySet().iterator(); + while(in.hasNext()) + { + Map.Entry me = (Map.Entry)in.next(); + Transition key = (Transition)me.getKey(); + Set value = (Set)me.getValue(); + + interleavingTrans.add(key); + Iterator bb = value.iterator(); + while(bb.hasNext()) + { + interleavingTrans.add((Transition)bb.next()); + } + } + } + + public static void printMap(HashMap> tranSet) + { + //long number = 0; + Iterator it = tranSet.keySet().iterator(); + if(!it.hasNext()) + { + System.out.println("this transition type is null"); + } + while(it.hasNext()) + { + Transition key = (Transition)it.next(); + HashSet value = tranSet.get(key); + System.out.print(key.getFullLabel()+" " ); + Iterator bb = value.iterator(); + while(bb.hasNext()) + { + //number++; + System.out.print(((Transition)bb.next()).getFullLabel()+","); + } + System.out.println(); + } + //System.out.println("number"+number); + } + + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/SearchDepFromState.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/SearchDepFromState.java new file mode 100644 index 000000000..46e6fbd8d --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/por1/SearchDepFromState.java @@ -0,0 +1,275 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.por1; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LPNTranRelation; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LpnTranList; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; + +/** + * in this approach, we do not consider transition interleaving + * @author Administrator + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class SearchDepFromState { + + private Set>> initialDepTrans; + private Set>> initialInterleavingTrans; + + private HashSet interleavingTrans = new HashSet(); + private HashMap> indepTranSet = new HashMap>(); + private HashMap> interleavingSet = new HashMap>(); + + + public SearchDepFromState(StateGraph[] lpnList,LPNTranRelation lpnTranRelation) + { + this.getInitialDepTran(lpnTranRelation); //get dependent and interleaving transitions + this.setInterleavingTrans(initialInterleavingTrans); + + if(initialDepTrans.size() !=0 || initialInterleavingTrans.size() !=0) + { + this.setInitIndepTrans(lpnList); //set independent number: n*(n-1) + this.reduceIndepTrans(initialDepTrans); + this.reduceIndepTrans(initialInterleavingTrans); +// System.out.println("final indep:"); +// this.printMap(indepTranSet); + } + else + { + System.out.println("do not call lpnTranRelation.getDep seccessful!"); + indepTranSet = null; + } + /* + System.out.println("print original depTranSet"); + this.printSet(initialDepTrans); + System.out.println("print original interleavingSet"); + this.printSet(initialInterleavingTrans); + //this.printMap(interleavingSet); + */ + + + } + + public HashMap> getIndepTranSet() + { + return this.indepTranSet; + } + + public HashSet getInterleavingTrans() + { + return this.interleavingTrans; + } + + public HashMap> getInterleavingSet() + { + return this.interleavingSet; + } + + /** + * get individual dependent transition + * get initial interleaving transition + * @param lpnTranRelation + */ + private void getInitialDepTran(LPNTranRelation lpnTranRelation) + { + lpnTranRelation.findCompositionalDependencies(); + lpnTranRelation.printCompositionalDependencies(); + //get individual dependent + initialDepTrans = lpnTranRelation.getDependentTrans(); + //get interleaving + initialInterleavingTrans = lpnTranRelation.getInterleavingTrans(); + this.setInterleavingSet(initialInterleavingTrans); + +// System.out.println("print original depTranSet"); +// this.printSet(initialDepTrans); +// System.out.println("print original interleavingSet"); +// this.printSet(initialInterleavingTrans); + + } + + private void setInterleavingTrans(Set>> initialInterleavingTrans) + { + Iterator in = initialInterleavingTrans.iterator(); + while(in.hasNext()) + { + Map.Entry me = (Map.Entry)in.next(); + Transition key = (Transition)me.getKey(); + Set value = (Set)me.getValue(); + + interleavingTrans.add(key); + Iterator bb = value.iterator(); + while(bb.hasNext()) + { + interleavingTrans.add((Transition)bb.next()); + } + } + } + private void setInterleavingSet(Set>> initialInterleavingTrans) + { + Iterator in = initialInterleavingTrans.iterator(); + while(in.hasNext()) + { + Map.Entry me = (Map.Entry)in.next(); + Transition key = (Transition)me.getKey(); + Set value = (Set)me.getValue(); + + HashSet key_inter = this.interleavingSet.get(key); + if(key_inter == null) + { + key_inter = new HashSet(); + this.interleavingSet.put(key, key_inter); + } + Iterator bb = value.iterator(); + while(bb.hasNext()) + { + key_inter.add((Transition)bb.next()); + } + } + } + /** + * get all transition, save to indepTranSet(Initial),independent number: n*(n-1) + * @param lpnList + * @return + */ + private void setInitIndepTrans(StateGraph[] lpnList) + { + //get all transitions + LpnTranList allTran = new LpnTranList(); + //for(StateGraph sg : lpnList) + //{ + // TODO: (future) need to user our transitions. + /* + LpnTranList trans = sg.getLpn().getTransitions(); + for(LPNTran tran: trans) + { + allTran.add(tran); + } + */ + //} + //save to indepTranSet + for(Transition key: allTran) + { + HashSet value = indepTranSet.get(key); + if(value == null) + { + value = new HashSet(); + indepTranSet.put(key, value); + } + for(Transition t: allTran) + { + if(t!=key) + value.add(t); + } + } + } + + private void reduceIndepTrans(Set>> initialDepTrans) + { + Iterator it = initialDepTrans.iterator(); + while(it.hasNext()) + { + Map.Entry me = (Map.Entry)it.next(); + Transition key = (Transition)me.getKey(); + Set value = (Set)me.getValue(); + Iterator itor = value.iterator(); + while(itor.hasNext()) + { + Transition tran = (Transition)itor.next(); + //reduce indep + this.reduceIndepSet_pair(key, tran); + this.reduceIndepSet_pair(tran, key); + } + } + } + + /** + * refine independent set{minus (key,tran) and (tran, key)} + * @param key + * @param tran + */ + private void reduceIndepSet_pair(Transition key, Transition tran) + { + HashSet value = indepTranSet.get(key); + if(value != null) + { + Iterator it = value.iterator(); + while(it.hasNext()) + { + Transition object = (Transition)it.next(); + if(object == tran) + { + value.remove(object); + break; + } + } + } + } + + public static void printMap(HashMap> tranSet) + { + long number = 0; + Iterator it = tranSet.keySet().iterator(); + if(!it.hasNext()) + { + System.out.println("this transition type is null"); + } + while(it.hasNext()) + { + Transition key = (Transition)it.next(); + HashSet value = tranSet.get(key); + System.out.print(key.getFullLabel()+" " ); + Iterator bb = value.iterator(); + while(bb.hasNext()) + { + number++; + System.out.print(((Transition)bb.next()).getFullLabel()+","); + } + System.out.println(); + } + System.out.println("number"+number); + } + + public static void printSet(Set>> tranSet) + { + Iterator in = tranSet.iterator(); + if(!in.hasNext()) + { + System.out.println("this transition type is null"); + } + while(in.hasNext()) + { + Map.Entry me = (Map.Entry)in.next(); + Transition key = (Transition)me.getKey(); + Set value = (Set)me.getValue(); + System.out.print(key.getFullLabel()+" " ); + Iterator bb = value.iterator(); + while(bb.hasNext()) + { + System.out.print(((Transition)bb.next()).getFullLabel()+","); + } + System.out.println(); + } + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/DesignUnit.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/DesignUnit.java new file mode 100644 index 000000000..34cea0cdb --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/DesignUnit.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.project; +/** +* +* @author ldmtwo +* @author Chris Myers +* @author iBioSim Contributors +* @version %I% +*/ +///* +// * To change this template, choose Tools | Templates +// * and open the template in the editor. +// */ +//package platu.project; +// +//import java.util.Set; +// +//import lmoore.TimedStateGraph; +//import platu.lpn.LPN; +//import platu.stategraph.StateGraph; +// +///** +// * +// * @author ldtwo +// */ +//public class DesignUnit { +// +// public LPN lpnModel=null; +// public LPN sgModel; +// public Set duSet; +// +// public DesignUnit() { +// } +// +// public DesignUnit( Set duSet) { +// this.duSet = duSet; +// } +// +// public DesignUnit(LPN lpnModel, LPN sgmodel) { +// this.lpnModel = lpnModel; +// this.sgModel = sgmodel; +// } +// +// public DesignUnit(LPN lpnModel) { +// this.lpnModel = lpnModel; +// } +// +// /** +// * @return the lpnmodel +// */ +// public LPN getLPNModel() { +// if(lpnModel==null)return reduce(); +// return lpnModel; +// } +// +// +// +// public LPN reduce() { +// LPN lpn, ret=null; +// for (DesignUnit du : duSet) { +// if(ret==null) +// if (du.lpnModel == null) { +// ret = du.reduce(); +// } else { +// ret = du.getLPNModel(); +// }else +// if (du.lpnModel == null) { +// lpn = du.reduce(); +// ret.compose(lpn, "tmp-"+System.currentTimeMillis()+".lpn"); +// } else { +// lpn = du.getLPNModel(); +// ret.compose(lpn, "tmp-"+System.currentTimeMillis()+".lpn"); +// } +// } +// return ret; +// } +// +// /** +// * @return the du +// */ +// public Set getDu() { +// return duSet; +// } +// +// /** +// * @param du the du to set +// */ +// public void setDu(Set du) { +// this.duSet = du; +// } +// +// /** +// * @return the sgModel +// */ +// public StateGraph getSGModelUntimed() { +// return (StateGraph) sgModel; +// } +// public TimedStateGraph getSGModel() { +// return (TimedStateGraph) sgModel; +// } +// +// /** +// * @param sgModel the sgModel to set +// */ +// public void setSgModel(TimedStateGraph sgModel) { +// this.sgModel = sgModel; +// } /** +// * @param sgModel the sgModel to set +// */ +// public void setSgModel(StateGraph sgModel) { +// this.sgModel = sgModel; +// } +//} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/IDGenerator.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/IDGenerator.java new file mode 100644 index 000000000..6cbd796fe --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/IDGenerator.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package edu.utah.ece.async.lema.verification.platu.project; + +import java.util.HashMap; + +/** + * + * @author ldmtwo + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class IDGenerator extends HashMap { + private static final long serialVersionUID = 98976418277654L; + + private int next = 0; + + public IDGenerator() { + super(100000); + } + + public IDGenerator(int size) { + super(size); + } + + // @Override + // public int size() { + // return next; + // } + + public boolean add(T item) { + return next == tryInsert(item); + } + + /** + * If the item does not exist, then insert. Return the unique ID for that + * item. + * + * @param item + * @return + */ + public int tryInsert(T item) { + if (containsKey(item)) { + return get(item); + } + int ID = next++; + put(item, ID); + return ID; + } + + public int test(T item) { + if (containsKey(item)) { + return get(item); + } + return next; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/PrintStackTrace.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/PrintStackTrace.java new file mode 100644 index 000000000..19f9d736e --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/PrintStackTrace.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package edu.utah.ece.async.lema.verification.platu.project; + +/** + * + * @author ldmtwo + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class PrintStackTrace extends Exception{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + public PrintStackTrace() { + this.printStackTrace(); + } + + public PrintStackTrace(String s) { + super(s); + this.printStackTrace(); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/PrjState.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/PrjState.java new file mode 100644 index 000000000..87f3da50d --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/PrjState.java @@ -0,0 +1,251 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.project; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class PrjState { + protected State[] stateArray; + private PrjState father; + private PrjState child; + /** + * A hash map recording the transition-state flow information at current global state. + * Key: outgoing transition from current state. + * Value: next global state reached by the corresponding outgoing transition. + */ + protected HashMap nextGlobalStateMap; + + public PrjState() { + stateArray = null; + father = null; + child = null; + } + + public PrjState(final State[] other) { + stateArray = other; + father = null; + child = null; + if (Options.getOutputSgFlag() || Options.getMarkovianModelFlag()) + nextGlobalStateMap = new HashMap(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(stateArray); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + + PrjState other = (PrjState) obj; + if(this.stateArray == other.stateArray) + return true; + if (!Arrays.equals(stateArray, other.stateArray)) + return false; + return true; + } + + public State get(int index) { + return stateArray[index]; + } + + public void add(int index, State other) { + stateArray[index] = other; + } + + public State[] toStateArray() { + return stateArray; + } + + public void setFather(final PrjState state) { + this.father = state; + } + + public void setChild(final PrjState state) { + this.child = state; + } + + public PrjState getFather() { + return this.father; + } + + public PrjState getChild() { + return this.child; + } + + @Override + public String toString() { + String line =""; + for(int i = 0; i < stateArray.length; i++) { + line += stateArray[i].toString()+"+"+stateArray[i].getLpn().getLabel() + " "; + } + return line; +// return toList(stateArray).toString(); + } +// public void print(final LPN[] lpnList) { +// for(int i = 0; i < stateArray.length; i++) { +// System.out.print(i +": "); +// stateArray[i].print(lpnList[i].getVarIndexMap()); +// System.out.println(); +// } +// } + + public void print(final LPN[] lpnList) { + for(int i = 0; i < stateArray.length; i++) { + System.out.println(lpnList[i].getLabel() + ".lpn" +": "); + //stateArray[i].print(lpnList[i].getVarIndexMap()); + stateArray[i].printStateInfo(); + System.out.println(); + } + } + + public static final Collection toList(Object[] arr) { + Set l = new HashSet(1); + l.addAll(Arrays.asList(arr)); + return l; + } + + public static final Object[] toArray(Collection set) { + Object[] arr = new Object[set.size()]; + int idx = 0; + for (Object i : set) { + arr[idx++] = i; + } + return arr; + } + +// public void setTranOut(Transition tran, PrjState nextState) { +// nextStateMap.put(tran, nextState); +// } + +// public Transition getOutgoingTranToState(PrjState nextState) { +// return nextStateMap.getKey(nextState); +// } + +// public void setTranIn(Transition tran, PrjState prevState) { +// prevStateMap.put(tran, prevState); +// } + +// public Transition getIncomingTranFromState(PrjState prevState) { +// return prevStateMap.getKey(prevState); +// } + +// public void setNextStateMap(HashMap map) { +// this.nextStateMap = map; +// } +// +// public HashMap getNextStateMap() { +// return nextStateMap; +// } + + public State[] getStateArray() { + return stateArray; + } + + + public void addNextGlobalState(Transition tran, PrjState nextPrjState) { + this.nextGlobalStateMap.put(tran, nextPrjState); + } + +// public PrjState getNextGlobalState(Transition outTran) { +// return nextGlobalStateMap.get(outTran); +// } +// + +// /** +// * This method uses local state-transition information to search for the next global states of +// * this current global state, and returns a set of such next global states. The search +// * is performed based on the local states that this current global state is composed of. For example, assume a current +// * global state S0 is composed of n (n>=1) local states: s_00,s_10,s_20...,s_n0. Given the outgoing transition, outTran, +// * it finds in each of the local state, namely s_00, s_10, s_20, ..., s_n0, their next local states, and then pieces them +// * together to form the next global state. Next, it grabs the equivalent one from the global state set. The obtained is the +// * next global state reached from S0 by taking outTran, and it is returned. +// * @param outTran +// * @param globalStateSet +// * @return +// */ +// public PrjState getNextPrjState(Transition outTran, StateSetInterface globalStateSet) { +// return null; +//// State[] nextStateArray = new State[this.toStateArray().length]; +//// for (State curLocalSt : this.toStateArray()) { +//// State nextLocalSt = curLocalSt.getNextLocalState(outTran); +//// if (nextLocalSt != null) { // outTran leads curLocalSt to a next state. +//// nextStateArray[curLocalSt.getLpn().getLpnIndex()] = nextLocalSt;//nextOtherLocalSt.clone(); +//// } +//// else { // No nextLocalSt was found. Transition outTran did not change this local state. +//// nextStateArray[curLocalSt.getLpn().getLpnIndex()] = curLocalSt; +//// } +//// } +//// PrjState tmpPrjSt = new PrjState(nextStateArray); +//// if (((HashSetWrapper)globalStateSet).get(tmpPrjSt) == null) +//// throw new NullPointerException("Next global state was not found."); +//// else +//// return ((HashSetWrapper) globalStateSet).get(tmpPrjSt); +// +// } + + public HashMap getNextGlobalStateMap() { + return nextGlobalStateMap; + } + +// /** +// * Return a set of outgoing transitions from this PrjState. +// * @return +// */ +// public Set getOutgoingTrans() { +// Set outgoingTrans = new HashSet(); +// for (State curLocalSt : this.toStateArray()) +// outgoingTrans.addAll(curLocalSt.getOutgoingTranSet()); +// return outgoingTrans; +// } + + /** + * Return the prjState label, which is the concatenation of local state labels. + * @return + */ + public String getLabel() { + String prjStateLabel = ""; + for (State localSt : this.toStateArray()) { + prjStateLabel += localSt.getLabel() + "_"; + } + return prjStateLabel.substring(0, prjStateLabel.lastIndexOf("_")); + } +} + diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/Project.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/Project.java new file mode 100644 index 000000000..83be4288e --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/Project.java @@ -0,0 +1,587 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.project; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Observer; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.swing.JProgressBar; + +import org.antlr.runtime.ANTLRFileStream; +import org.antlr.runtime.CommonTokenStream; +import org.antlr.runtime.TokenStream; + +import edu.utah.ece.async.ibiosim.dataModels.util.GlobalConstants; +import edu.utah.ece.async.ibiosim.dataModels.util.exceptions.BioSimException; +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Translator; +import edu.utah.ece.async.lema.verification.platu.logicAnalysis.Analysis; +import edu.utah.ece.async.lema.verification.platu.logicAnalysis.CompositionalAnalysis; +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.markovianAnalysis.MarkovianAnalysis; +import edu.utah.ece.async.lema.verification.platu.markovianAnalysis.PerfromTransientMarkovAnalysisThread; +import edu.utah.ece.async.lema.verification.platu.markovianAnalysis.ProbGlobalStateSet; +import edu.utah.ece.async.lema.verification.platu.markovianAnalysis.ProbLocalStateGraph; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LPNTranRelation; +import edu.utah.ece.async.lema.verification.platu.platuLpn.PlatuLPN; +import edu.utah.ece.async.lema.verification.platu.platuLpn.io.Instance; +import edu.utah.ece.async.lema.verification.platu.platuLpn.io.PlatuInstLexer; +import edu.utah.ece.async.lema.verification.platu.platuLpn.io.PlatuInstParser; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; +import edu.utah.ece.async.lema.verification.timed_state_exploration.octagon.Equivalence; +import edu.utah.ece.async.lema.verification.timed_state_exploration.octagon.Octagon; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.ContinuousUtilities; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.Zone; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Project { + + protected String label; + + /* 1. Each design unit has an unique label index. + * 2. The indices of all design units are sequential starting from 0. + * */ + protected List designUnitSet; + + /* The list for timing analysis */ +// protected List designUnitTimedSet; + + protected LPNTranRelation lpnTranRelation = null; + + protected CompositionalAnalysis analysis = null; + + private Observer observer; + + private static String separator = GlobalConstants.separator; + + public Project() { + this.label = ""; + this.designUnitSet = new ArrayList(1); + lpnTranRelation = new LPNTranRelation(this.designUnitSet); + } + + public Project(LPN lpn) { + this.label = ""; + this.designUnitSet = new ArrayList(1); + StateGraph stateGraph = new StateGraph(lpn); + designUnitSet.add(stateGraph); + + } + + /** + * If the OptionsFlag is false, then this constructor is identical to + * Poject(LhpnFile lpn). If the OptionsFlag is true, this constructor uses + * StateGraph_timed objects. + * + * @author Andrew N. Fisher + * + * @param lpn + * The lpn under consideration. + * @param OptionsFlag + * True for timing analysis and false otherwise. The option should match + * Options.getTimingAnalysisFlag(). + */ +// public Project(LhpnFile lpn, boolean OptionsFlag) +// { +// if(Options.getTimingAnalysisFlag()) +// { +// this.label = ""; +// this.designUnitSet = new ArrayList(0); +// this.designUnitTimedSet = new ArrayList(1); +// StateGraph_timed stategraph = new StateGraph_timed(lpn); +// designUnitTimedSet.add(stategraph); +// } +// else +// { +// this.label = ""; +// this.designUnitSet = new ArrayList(1); +// StateGraph stateGraph = new StateGraph(lpn); +// designUnitSet.add(stateGraph); +// } +// } + + public Project(ArrayList lpns) { + this.label = ""; + this.designUnitSet = new ArrayList(lpns.size()); + if (!Options.getMarkovianModelFlag()) + for (int i=0; i varValMap = new HashMap(); + State[] initStateArray = new State[lpnCnt]; + for (int index = 0; index < lpnCnt; index++) { + LPN curLpn = sgArray[index].getLpn(); + StateGraph curSg = sgArray[index]; + initStateArray[index] = curSg.genInitialState(); + int[] curVariableVector = initStateArray[index].getVariableVector(); + varValMap = curLpn.getAllVarsWithValuesAsInt(curVariableVector); + } + + // Adjust the value of the input variables in LPN in the initial state. + // Add the initial states into their respective state graphs. + for (int index = 0; index < lpnCnt; index++) { + StateGraph curSg = sgArray[index]; + // If this is a timing analysis, the boolean inequality variables + // must be updated. + if(Options.getTimingAnalysisFlag()){ + // First create a zone with the continuous variables. + State[] ls = new State[1]; + ls[0] = initStateArray[index]; + + Equivalence z = null; + if(Options.getTimingAnalysisType().equals("zone")){ + z = new Zone(ls, true); + } + else{ + z = new Octagon(ls, true); + } + ContinuousUtilities.updateInitialInequalities(z, ls[0]); + initStateArray[index] = curSg.genInitialState(); + } + initStateArray[index].update(curSg, varValMap, curSg.getLpn().getVarIndexMap()); + initStateArray[index] = curSg.addState(initStateArray[index]); + } + + // Initialize the zones for the initStateArray, if timining is enabled. +// if(Options.getTimingAnalysisFlag()) +// { +// for(int index =0; index < lpnCnt; index++) +// { +// if(sgArray[index] instanceof StateGraph_timed) +// { +// +// } +// } +// } + +// if (Options.getTimingAnalysisFlag()) { +// new TimingAnalysis(sgArray); +// return; +// } +// else if(!Options.getTimingAnalysisFlag()) { +// Analysis tmp = new Analysis(sgArray, initStateArray, lpnTranRelation, Options.getSearchType()); +// // Analysis tmp = new Analysis(lpnList, curStateArray, +// // lpnTranRelation, "dfs_por"); +// //Analysis tmp = new Analysis(modArray, initStateArray, lpnTranRelation, "dfs"); +// //Analysis tmp = new Analysis(modArray, initStateArray, lpnTranRelation, "dfs_noDisabling"); +// } +// else { +// System.out.println("---> Error: wrong value for option 'timingAnalysis'"); +// return; +// } + + /* Entry point for the timed analysis. */ +// if(Options.getTimingAnalysisFlag()) +// { +// Analysis_Timed dfsTimedStateExploration = new Analysis_Timed(sgArray); +// dfsTimedStateExploration.search_dfs_timed(sgArray, initStateArray); +// return new StateGraph[0]; +// } + + Analysis dfsStateExploration = new Analysis(sgArray); + dfsStateExploration.addObserver(observer); + if (!Options.getMarkovianModelFlag()) { + if (Options.getPOR().toLowerCase().equals("off")) { + // DFS state exploration without any state reduction. + dfsStateExploration.search_dfs(sgArray, initStateArray); + } + if (Options.getPOR().toLowerCase().equals("tb")) { + dfsStateExploration.searchPOR_taceback(sgArray, initStateArray); + } + else if (Options.getPOR().toLowerCase().equals("behavioral")) { + //CompositionalAnalysis compAnalysis = new CompositionalAnalysis(); + CompositionalAnalysis.compositionalFindSG(sgArray); + // TODO: temporarily commented out POR with behavioral analysis + //dfsStateExploration.searchPOR_behavioral(sgArray, initStateArray, lpnTranRelation, "state"); + } + long elapsedTimeMillis = System.currentTimeMillis() - startReachability; + float elapsedTimeSec = elapsedTimeMillis/1000F; + System.out.println("---> total runtime for reachability analysis: " + elapsedTimeSec + " sec\n"); + if (Options.getOutputLogFlag()) { + if (Options.getPOR().toLowerCase().equals("off")) { + outputRuntimeLog(false, elapsedTimeSec); + } + else + outputRuntimeLog(true, elapsedTimeSec); + } + if (Options.getOutputSgFlag()) { + for (int i=0; i total runtime for reachability analysis: " + elapsedTimeSecReachability + " sec"); + if (Options.getOutputLogFlag()) + outputRuntimeLog(false, elapsedTimeSecReachability); + System.gc(); +//// // -------------------- Temp: steady-state analysis -------------- +// System.out.println("--------- Steady State Analysis ---------"); +// long startSteadyState = System.currentTimeMillis(); +// MarkovianAnalysis markovianAnalysis = new MarkovianAnalysis(globalStateSet); +// double tolerance = 0.0000000001; +// PrjState initialSt = ((ProbGlobalStateSet) globalStateSet).getInitialState(); +// markovianAnalysis.performSteadyStateMarkovianAnalysis(tolerance, null, initialSt, null); +// dfsStateExploration.drawGlobalStateGraph(sgArray, initialSt, globalStateSet); +// long elapsedTimeMillisSteadyState = System.currentTimeMillis() - startSteadyState; +// float elapsedTimeSecSteadyState = elapsedTimeMillisSteadyState/1000F; +// System.out.println("---> total runtime for steady state analysis: " + elapsedTimeSecSteadyState + " sec"); +// // ------------------------------------------------------------ + + // -------------------- Temp: transient analysis -------------- + System.out.println("--------- Transient Analysis ---------"); + long startTransientAnalysis = System.currentTimeMillis(); + MarkovianAnalysis markovianAnalysis = new MarkovianAnalysis(globalStateSet); + + + // --- toggle_switch --- + double timeLimit = 5000.0; + double printInterval = 100.0; + double timeStep = 100.0; + double absError = 1.0e-9; + String prop = "Pr=?{PF[<=5000]((LacI>40)&(TetR<20))}"; + //String prop = "Pr=?{PF[<=5000]((TetR>40)&(LacI<20))}"; + // --- end of toggle_switch --- + + // === C-element circuits === +// double timeLimit = 2100.0; +// double printInterval = 100.0; +// double timeStep = 100.0; +// double absError = 1.0e-9; +// // --- majority --- +// String prop = "Pr=?{PF[<=2100]((E>40)&(C<20))}"; + // --- end of majority --- +//////// +//////// // --- speedInd --- +//////// //String prop = "Pr=?{PF[<=2100]((S2>80)&(S3<20))}"; +//////// // --- end of speedInd --- +//////// +//////// // --- toggle --- +//////// //String prop = "Pr=?{PF[<=2100]((Z>80)&(Y<40))}"; +//////// // --- end of toggle --- +//////// +//////// +// // ======================================== + JProgressBar progress = new JProgressBar(0, 100); + + PerfromTransientMarkovAnalysisThread performMarkovAnalysisThread = new PerfromTransientMarkovAnalysisThread( + markovianAnalysis, progress); + String[] condition = Translator.getProbpropParts(Translator.getProbpropExpression(prop)); + boolean globallyTrue = false; + if (prop.contains("PF")) { + condition[0] = "true"; + } + else if (prop.contains("PG")) { + condition[0] = "true"; + globallyTrue = true; + } + performMarkovAnalysisThread.start(timeLimit, timeStep, printInterval, absError, condition, globallyTrue); + + try { + performMarkovAnalysisThread.join(); + } catch (InterruptedException e) { + //JOptionPane.showMessageDialog(Gui.frame, "Error In Execution!", "Error In Execution", JOptionPane.ERROR_MESSAGE); + e.printStackTrace(); + } + //dfsStateExploration.drawGlobalStateGraph(sgArray, globalStateSet.getInitialState(), globalStateSet, true); + //markovianAnalysis.printStateSetStatus(globalStateSet, "end of transient analysis"); + long elapsedTimeMillisTransient = System.currentTimeMillis() - startTransientAnalysis; + float elapsedTimeSecTransient = elapsedTimeMillisTransient/1000F; + System.out.println("---> total runtime for transient analysis: " + elapsedTimeSecTransient + " sec"); + // ------------------------------------------------------------ +// +// // -------------------- Temp: nested analysis -------------- +// // ------------------------------------------------------------ + } +// if (Options.getOutputSgFlag()) +// for (int i=0; i readLpn(final String src_file) { + Set lpnSet = null; + + try { + if (!src_file.endsWith(".lpn")) { + System.err.println("Invalid file extention"); + System.exit(1); + } + +// ANTLRFileStream input = new ANTLRFileStream(src_file); +// PlatuGrammarLexer lexer = new PlatuGrammarLexer(input); +// TokenStream tokenStream = new CommonTokenStream(lexer); +// PlatuGrammarParser parser = new PlatuGrammarParser(tokenStream); +// lpnSet = parser.lpn(this); + + } catch (Exception ex) { + Logger.getLogger(Project.class.getName()).log(Level.SEVERE, null, + ex); + } + + return lpnSet; + } + + private static void outputRuntimeLog(boolean isPOR, float runtime) { + try { + String fileName = null; + if (isPOR) { + fileName = Options.getPrjSgPath() + separator + Options.getLogName() + "_" + + Options.getPOR() + "_" + Options.getCycleClosingMthd() + "_" + + Options.getCycleClosingStrongStubbornMethd() + "_runtime.log"; + } + else + fileName = Options.getPrjSgPath() + Options.getLogName() + "_full_runtime.log"; + BufferedWriter out = new BufferedWriter(new FileWriter(fileName)); + out.write("runtime(sec)\n"); + out.write(runtime + "\n"); + out.close(); + } + catch (Exception e) { + e.printStackTrace(); + System.err.println("Error producing local state graph as dot file."); + } + } + + public void readLpn(List fileList) { + for(String srcFile : fileList){ + if (!srcFile.endsWith(".lpn")) { + System.err.println("Invalid file extention"); + System.exit(1); + } + + ANTLRFileStream input = null; + try { + input = new ANTLRFileStream(srcFile); + } + catch (IOException e) { + System.err.println("error: error reading " + srcFile); + System.exit(1); + } + + PlatuInstLexer lexer = new PlatuInstLexer(input); + TokenStream tokenStream = new CommonTokenStream(lexer); + PlatuInstParser parser = new PlatuInstParser(tokenStream); + + parser.parseLpnFile(this); + } + + PlatuInstParser.includeSet.removeAll(fileList); + for(String srcFile : PlatuInstParser.includeSet){ + if (!srcFile.endsWith(".lpn")) { + System.err.println("Invalid file extention"); + System.exit(1); + } + + ANTLRFileStream input = null; + try { + input = new ANTLRFileStream(srcFile); + } + catch (IOException e) { + System.err.println("error: error reading " + srcFile); + System.exit(1); + } + + PlatuInstLexer lexer = new PlatuInstLexer(input); + TokenStream tokenStream = new CommonTokenStream(lexer); + PlatuInstParser parser = new PlatuInstParser(tokenStream); + + parser.parseLpnFile(this); + } + + edu.utah.ece.async.lema.verification.platu.platuLpn.PlatuLPN.nextID = 1; + + HashMap instanceMap = new HashMap(); + for(Instance inst : PlatuInstParser.InstanceList){ + PlatuLPN lpn = PlatuInstParser.LpnMap.get(inst.getLpnLabel()); + if(lpn == null){ + System.err.println("error: class " + inst.getLpnLabel() + " does not exist"); + return; + } + + PlatuLPN instLpn = lpn.instantiate(inst.getName()); + + instanceMap.put(instLpn.getLabel(), instLpn); + this.designUnitSet.add(instLpn.getStateGraph()); + } + + // TODO: (irrelevant) Is this really needed??? + /* + for(StateGraph sg : this.designUnitSet){ + sg.getLpn().setGlobals(this.designUnitSet); + } + */ + + for(Instance inst : PlatuInstParser.InstanceList){ + PlatuLPN dstLpn = instanceMap.get(inst.getName()); + if(dstLpn == null){ + System.err.println("error: instance " + inst.getName() + " does not exist"); + return; + } + + List argumentList = dstLpn.getArgumentList(); + List varList = inst.getVariableList(); + List modList = inst.getModuleList(); + + if(argumentList.size() != varList.size()){ + System.err.println("error: incompatible number of arguments for instance " + inst.getName()); + return; + } + + for(int i = 0; i < argumentList.size(); i++){ + PlatuLPN srcLpn = instanceMap.get(modList.get(i)); + if(srcLpn == null){ + System.err.println("error: instance " + modList.get(i) + " does not exist"); + return; + } + + String outputVar = varList.get(i); + String inputVar = argumentList.get(i); + srcLpn.connect(outputVar, dstLpn, inputVar); + } + } + } + + /** + * @return the designUnitSet + */ + public List getDesignUnitSet() { + return designUnitSet; + } + + /** + * Validates each lpn's input variables are driven by another lpn's output. + */ + protected void validateInputs(){ // Changed protection level. ANF + boolean error = false; + for(StateGraph sg : designUnitSet){ + for(String input : sg.getLpn().getAllInputs().keySet()){ + boolean connected = false; + for(StateGraph sg2 : designUnitSet){ + if(sg == sg2) + continue; + if(sg2.getLpn().getAllOutputs().keySet().contains(input)){ + connected = true; + break; + } + } + if(!connected){ + error = true; + System.err.println("error in lpn " + sg.getLpn().getLabel() + ": input variable '" + input + "' is not dependent on an output"); + } + } + } + + if(error){ + System.exit(1); + } + } + + public void setObserver(Observer observer) + { + this.observer = observer; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/prjStateTimed.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/prjStateTimed.java new file mode 100644 index 000000000..6f837d600 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/project/prjStateTimed.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.project; + +import java.util.Arrays; + +import edu.utah.ece.async.lema.verification.platu.TimingAnalysis.Zone1; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class prjStateTimed extends PrjState { + + private Object zone; + + public prjStateTimed(final State[] other, Object zone) { + this.stateArray = other; + this.zone = zone; + } + + public prjStateTimed(final State[] other) { + stateArray = other; + } + + @Override + public boolean equals(final Object other) { + return super.equals(other) && zone.equals(((prjStateTimed) other).zone); + } + + @Override + public int hashCode() { + return super.hashCode()*31+zone.hashCode(); + } + + /** + * @return the zone + */ + public Zone1 getZone() { + return (Zone1) zone; + } + + /** + * @param zone the zone to set + */ + public void setZone(Object zone) { + this.zone = zone; + } + + @Override + public String toString() { + return Arrays.toString(stateArray)+zone.hashCode(); + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/State.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/State.java new file mode 100644 index 000000000..835a2a1b5 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/State.java @@ -0,0 +1,592 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.stategraph; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Set; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.common.PlatuObj; +import edu.utah.ece.async.lema.verification.platu.platuLpn.DualHashMap; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LpnTranList; +import edu.utah.ece.async.lema.verification.platu.platuLpn.VarSet; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zone.TimedState; + +/** + * State + * @author Administrator + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class State extends PlatuObj { + + public static int[] counts = new int[15]; + + protected int[] marking; + protected int[] vector; + protected boolean[] tranVector; // an indicator vector showing whether each transition is enabled or not + private int hashVal = 0; + protected LPN lpn; + private int index; + private boolean localEnabledOnly; + protected boolean failure = false; + + // The TimingState that extends this state with a zone. Null if untimed. + //protected TimedState timeExtension; + + // A list of all the TimedStates that are time extensions of this state. + private ArrayList timeExtensions; + + @Override + public String toString() { +// String ret=Arrays.toString(marking)+""+ +// Arrays.toString(vector); +// return "["+ret.replace("[", "{").replace("]", "}")+"]"; + return this.print(); + } + + public State(final LPN lpn, int[] new_marking, int[] new_vector, boolean[] new_isTranEnabled) { + this.lpn = lpn; + this.marking = new_marking; + this.vector = new_vector; + if(new_isTranEnabled != null) + this.tranVector = new_isTranEnabled; + if (marking == null || vector == null || tranVector == null) { + new NullPointerException().printStackTrace(); + } + //Arrays.sort(this.marking); + //this.index = 0; + localEnabledOnly = false; + counts[0]++; + } + + public State(State other) { + if (other == null) { + new NullPointerException().printStackTrace(); + return; + } + + this.lpn = other.lpn; + this.marking = new int[other.marking.length]; + System.arraycopy(other.marking, 0, this.marking, 0, other.marking.length); + + this.vector = new int[other.vector.length]; + System.arraycopy(other.vector, 0, this.vector, 0, other.vector.length); + + this.tranVector = new boolean[other.tranVector.length]; + System.arraycopy(other.tranVector, 0, this.tranVector, 0, other.tranVector.length); + +// this.hashVal = other.hashVal; + this.hashVal = 0; + this.index = other.index; + this.localEnabledOnly = other.localEnabledOnly; + counts[0]++; + } + + // Temporarily commented out the two unused constructors, State() and State(Object otherState) + +// public State() { +// this.marking = new int[0]; +// this.vector = new int[0];//EMPTY_VECTOR.clone(); +// this.hashVal = 0; +// this.index = 0; +// localEnabledOnly = false; +// counts[0]++; +// } + //static PrintStream out = System.out; + +// public State(Object otherState) { +// State other = (State) otherState; +// if (other == null) { +// new NullPointerException().printStackTrace(); +// } +// +// this.lpnModel = other.lpnModel; +// this.marking = new int[other.marking.length]; +// System.arraycopy(other.marking, 0, this.marking, 0, other.marking.length); +// +// // this.vector = other.getVector().clone(); +// this.vector = new int[other.vector.length]; +// System.arraycopy(other.vector, 0, this.vector, 0, other.vector.length); +// +// this.hashVal = other.hashVal; +// this.index = other.index; +// this.localEnabledOnly = other.localEnabledOnly; +// counts[0]++; +// } + + public void setLpn(final LPN thisLpn) { + this.lpn = thisLpn; + } + + public LPN getLpn() { + return this.lpn; + } + + @Override + public void setLabel(String lbl) { + + } + + @Override + public String getLabel() { + return "S" + getIndex(); + } + + /** + * This method returns the boolean array representing the status (enabled/disabled) of each transition in an LPN. + * @return + */ + public boolean[] getTranVector() { + return tranVector; + } + + @Override + public void setIndex(int newIndex) { + this.index = newIndex; + } + + @Override + public int getIndex() { + return this.index; + } + + public boolean hasNonLocalEnabled() { + return this.localEnabledOnly; + } + + public void hasNonLocalEnabled(boolean nonLocalEnabled) { + this.localEnabledOnly = nonLocalEnabled; + } + + @SuppressWarnings("static-method") + public boolean isFailure() { + return false;// getType() != getType().NORMAL || getType() != + // getType().TERMINAL; + } + + public static long tSum = 0; + + @Override + public State clone() { + counts[6]++; + State s = new State(this); + return s; + } + + public String print() { + DualHashMap VarIndexMap = this.lpn.getVarIndexMap(); + String newLine = System.getProperty("line.separator");//This will retrieve line separator dependent on OS. + String message = "State ID: " + index + newLine; + message += "LPN: " + lpn.getLabel() + newLine; + message += "Marking: ["; + for (int i : marking) { + message += i + ","; + } + message += "]" + newLine + "Vector: ["; + for (int i = 0; i < vector.length; i++) { + message += VarIndexMap.getKey(i) + "=>" + vector[i]+", "; + } + message += "]" + newLine + "Transition Vector: ["; + for (int i = 0; i < tranVector.length; i++) { + message += tranVector[i] + ","; + } + message += "]" + newLine + "Enabled Transition: ["; + for (int i = 0; i < tranVector.length; i++) { + if (tranVector[i]) { + message += lpn.getTransition(i).getLabel(); + } + } + message += "]" + newLine; + return message; + } + + @Override + public int hashCode() { + if(hashVal == 0){ + final int prime = 31; + int result = 1; + result = prime * result + ((lpn == null) ? 0 : lpn.getLabel().hashCode()); + result = prime * result + Arrays.hashCode(marking); + result = prime * result + Arrays.hashCode(vector); + result = prime * result + Arrays.hashCode(tranVector); + hashVal = result; + } + + return hashVal; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + + if (obj == null) + return false; + + if (getClass() != obj.getClass()) + return false; + + State other = (State) obj; + if (lpn == null) { + if (other.lpn != null) + return false; + } + else if (!lpn.equals(other.lpn)) + return false; + + if (!Arrays.equals(marking, other.marking)) + return false; + + if (!Arrays.equals(vector, other.vector)) + return false; + + if (!Arrays.equals(tranVector, other.tranVector)) + return false; + + return true; + } + + public void print(DualHashMap VarIndexMap) { + System.out.print("Marking: ["); + for (int i : marking) { + System.out.print(i + ","); + } + System.out.println("]"); + + System.out.print("Vector: ["); + for (int i = 0; i < vector.length; i++) { + System.out.print(VarIndexMap.getKey(i) + "=>" + vector[i]+", "); + } + System.out.println("]"); + + System.out.print("Transition vector: ["); + for (boolean bool : tranVector) { + System.out.print(bool + ","); + } + System.out.println("]"); + } + + /** + * @return the marking + */ + public int[] getMarking() { + return marking; + } + + public void setMarking(int[] newMarking) { + marking = newMarking; + } + + /** + * @return the vector + */ + public int[] getVariableVector() { + // new Exception("StateVector getVector(): "+s).printStackTrace(); + return vector; + } + + public HashMap getOutVector(VarSet outputs, DualHashMap VarIndexMap) { + HashMap outVec = new HashMap(); + for(int i = 0; i < vector.length; i++) { + String var = VarIndexMap.getKey(i); + if(outputs.contains(var) == true) + outVec.put(var, vector[i]); + } + + return outVec; + } + + public State getLocalState() { + //VarSet lpnOutputs = this.lpnModel.getOutputs(); + //VarSet lpnInternals = this.lpnModel.getInternals(); + Set lpnOutputs = this.lpn.getAllOutputs().keySet(); + Set lpnInternals = this.lpn.getAllInternals().keySet(); + DualHashMap varIndexMap = this.lpn.getVarIndexMap(); + + int[] outVec = new int[this.vector.length]; + + /* + * Create a copy of the vector of mState such that the values of inputs are set to 0 + * and the values for outputs/internal variables remain the same. + */ + for(int i = 0; i < this.vector.length; i++) { + String curVar = varIndexMap.getKey(i); + if(lpnOutputs.contains(curVar) ==true || lpnInternals.contains(curVar)==true) + outVec[i] = this.vector[i]; + else + outVec[i] = 0; + } + return new State(this.lpn, this.marking, outVec, this.tranVector); + } + + /** + * @return the enabledSet + */ + public static int[] getEnabledSet() { + return null;// enabledSet; + } + + public LpnTranList getEnabledTransitions() { + LpnTranList enabledTrans = new LpnTranList(); + for (int i=0; i newVector, DualHashMap VarIndexMap) { + int[] newVariableVector = new int[this.vector.length]; + + boolean newState = false; + for(int index = 0; index < vector.length; index++) { + String var = VarIndexMap.getKey(index); + int this_val = this.vector[index]; + + Integer newVal = newVector.get(var); + if(newVal != null) { + if(this_val != newVal) { + newState = true; + newVariableVector[index] = newVal; + } + else + newVariableVector[index] = this.vector[index]; + } + else + newVariableVector[index] = this.vector[index]; + } + if(newState == true) { + boolean[] newTranVector = SG.updateTranVector(this, this.marking, newVariableVector, null); + return new State(this.lpn, this.marking, newVariableVector, newTranVector); + } + return null; + } + + /** + * Return a new state if the newVector leads to a new state from this state; otherwise return null. + * States considered here include a vector indicating enabled/disabled state of each transition. + * @param newVector + * @param VarIndexMap + * @return + */ + public State update(HashMap newVector, DualHashMap VarIndexMap, + boolean[] newTranVector) { + int[] newStateVector = new int[this.vector.length]; + boolean newState = false; + for(int index = 0; index < vector.length; index++) { + String var = VarIndexMap.getKey(index); + int this_val = this.vector[index]; + Integer newVal = newVector.get(var); + if(newVal != null) { + if(this_val != newVal) { + newState = true; + newStateVector[index] = newVal; + } + else + newStateVector[index] = this.vector[index]; + } + else + newStateVector[index] = this.vector[index]; + } + if (!this.tranVector.equals(newTranVector)) + newState = true; + + if(newState == true) + return new State(this.lpn, this.marking, newStateVector, newTranVector); + + return null; + } + + static public void printUsageStats() { + System.out.printf("%-20s %11s\n", "State", counts[0]); + System.out.printf("\t%-20s %11s\n", "State", counts[10]); + // System.out.printf("\t%-20s %11s\n", "State", counts[11]); + // System.out.printf("\t%-20s %11s\n", "merge", counts[1]); + System.out.printf("\t%-20s %11s\n", "update", counts[2]); + // System.out.printf("\t%-20s %11s\n", "compose", counts[3]); + System.out.printf("\t%-20s %11s\n", "equals", counts[4]); + // System.out.printf("\t%-20s %11s\n", "conjunction", counts[5]); + System.out.printf("\t%-20s %11s\n", "clone", counts[6]); + System.out.printf("\t%-20s %11s\n", "hashCode", counts[7]); + // System.out.printf("\t%-20s %11s\n", "resembles", counts[8]); + // System.out.printf("\t%-20s %11s\n", "digest", counts[9]); + } +//TODO: (original) try database serialization + public File serialize(String filename) throws FileNotFoundException, + IOException { + File f = new File(filename); + ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(f)); + os.writeObject(this); + + os.close(); + return f; + } + + public static State deserialize(String filename) + throws FileNotFoundException, IOException, ClassNotFoundException { + File f = new File(filename); + ObjectInputStream os = new ObjectInputStream(new FileInputStream(f)); + State zone = (State) os.readObject(); + os.close(); + return zone; + } + + public static State deserialize(File f) throws FileNotFoundException, + IOException, ClassNotFoundException { + ObjectInputStream os = new ObjectInputStream(new FileInputStream(f)); + State zone = (State) os.readObject(); + os.close(); + return zone; + } + + public boolean failure(){ + return this.failure; + } + + public void setFailure(){ + this.failure = true; + } + + public void printStateInfo() { + System.out.print("Marking: ["); + for (int i=0; i < marking.length; i++) { + System.out.print(lpn.getPlaceList()[i] + "=" + marking[i] + ", "); + } + System.out.println("]"); + + System.out.print("Vector: ["); + for (int i = 0; i < vector.length; i++) { + System.out.print(lpn.getVarIndexMap().getKey(i) + "=" + vector[i]+", "); + } + System.out.println("]"); + System.out.print("Transition vector: ["); + for (boolean bool : tranVector) { + System.out.print(bool + ","); + } + System.out.println("]"); + String arrayStr = ""; + for (int i=0; i< tranVector.length; i++) { + if (tranVector[i]) { + arrayStr = arrayStr + lpn.getAllTransitions()[i].getFullLabel() + ", "; + } + } + System.out.println("enabled transitions: " + arrayStr); + } + + /** + * Getter for the TimingState that extends this state. + * @return + * The TimingState that extends this state if it has been set. Null, otherwise. + */ + public ArrayList getTimeExtension(){ + return timeExtensions; + } + + /** + * Setter for the TimingState that extends this state. + * @param s + * The TimingState that extends this state. + */ + public void setTimeExtension(ArrayList s){ + timeExtensions = s; + } + + public void addTimeExtension(TimedState s){ + if(timeExtensions == null){ + timeExtensions = new ArrayList(); + } + + timeExtensions.add(s); + } + + /** + * Get the current value of the variable according to the state. + * @param variable + * The variable of interest. + * @return + * The value of the variable as stored in the state. + */ + public int getCurrentValue(String variable){ + + // Get the index of the variable according to the LPN. + int index = lpn.getVarIndexMap().getValue(variable); + + return getCurrentValue(index); + } + + /** + * Get the current value of the variable according to the state. + * @param variableIndex + * The index of the variable of interest. + * @return + * The value of the variable as stored in the state. + */ + public int getCurrentValue(int variableIndex){ + return vector[variableIndex]; + } + + public String getFullLabel() { + String fullLabel = "S" + getIndex() + "(" + getLpn().getLabel() +")"; + return fullLabel; + } + + /** + * Returns the corresponding state graph that this state lives in. + * @return + */ + public StateGraph getStateGraph() { + return this.getLpn().getStateGraph(); + } + + public Set getOutgoingTranSet() { + return this.getStateGraph().getNextStateMap().get(this).keySet(); + } + + public State getNextLocalState(Transition outTran) { + return this.getStateGraph().getNextState(this, outTran); + } + } diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/StateGraph.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/StateGraph.java new file mode 100644 index 000000000..584febc3e --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/StateGraph.java @@ -0,0 +1,2307 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.platu.stategraph; + +import java.io.BufferedWriter; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map.Entry; + +import edu.utah.ece.async.ibiosim.dataModels.util.GlobalConstants; +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Place; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.lpn.Variable; +import edu.utah.ece.async.lema.verification.platu.common.IndexObjMap; +import edu.utah.ece.async.lema.verification.platu.logicAnalysis.Constraint; +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.platuLpn.DualHashMap; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LpnTranList; +import edu.utah.ece.async.lema.verification.platu.project.PrjState; +import edu.utah.ece.async.lema.verification.timed_state_exploration.octagon.Equivalence; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.ContinuousRecordSet; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.ContinuousUtilities; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.Event; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.EventSet; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.InequalityVariable; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.IntervalPair; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.LPNContAndRate; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.LPNContinuousPair; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.LPNTransitionPair; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.TimedPrjState; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.UpdateContinuous; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.Zone; + +import java.util.Set; +import java.util.Stack; + + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class StateGraph { + + protected State init = null; + protected IndexObjMap stateCache; + //protected IndexObjMap localStateCache; + protected HashMap state2LocalMap; + /** + * This field variable is inherited from Hao's code. His state does not store enabled transition array, and he uses this map to store + * enabled transitions in each local state. Since we store enabled transitions in each of our local state, the use of this map for storing + * enabled transitions is redundant. This field variable is used to store persistent sets for each local state instead. + */ + protected HashMap enabledSetTbl; + protected HashMap> nextStateMap; + protected List stateSet = new LinkedList(); + protected List frontierStateSet = new LinkedList(); + protected List entryStateSet = new LinkedList(); + protected List oldConstraintSet = new LinkedList(); + protected List newConstraintSet = new LinkedList(); + protected List frontierConstraintSet = new LinkedList(); + protected Set constraintSet = new HashSet(); + protected LPN lpn; + protected static Set> emptySet = new HashSet>(0); + private String separator = GlobalConstants.separator; + + public StateGraph(LPN lpn) { + this.lpn = lpn; + this.stateCache = new IndexObjMap(); + //this.localStateCache = new IndexObjMap(); + this.state2LocalMap = new HashMap(); + this.enabledSetTbl = new HashMap(); + this.nextStateMap = new HashMap>(); + } + + public LPN getLpn(){ + return this.lpn; + } + + public void printStates(){ + System.out.println(String.format("%-8s %5s", this.lpn.getLabel(), "|States| = " + stateCache.size())); + } + +// public Set getTranList(State currentState){ +// return this.nextStateMap.get(currentState).keySet(); +// } + + /** + * Finds reachable states from the given state. + * Also generates new constraints from the state transitions. + * @param baseState - State to start from + * @return Number of new transitions. + */ + public int constrFindSG(final State baseState){ + boolean newStateFlag = false; + int ptr = 1; + int newTransitions = 0; + Stack stStack = new Stack(); + Stack tranStack = new Stack(); + // TODO: What if we just read tranVector from baseState? + LpnTranList currentEnabledTransitions = getEnabled(baseState); + stStack.push(baseState); + tranStack.push(currentEnabledTransitions); + while (true){ + ptr--; + State currentState = stStack.pop(); + currentEnabledTransitions = tranStack.pop(); + for (Transition firedTran : currentEnabledTransitions) { + //System.out.println("firedTran: " + firedTran.getLabel() + "(" + firedTran.getLpn().getLabel() + ")"); + State newState = constrFire(firedTran,currentState); + State nextState = addState(newState); + newStateFlag = false; + if(nextState == newState){ + addFrontierState(nextState); + newStateFlag = true; + } +// StateTran stTran = new StateTran(currentState, firedTran, state); + if(nextState != currentState){ +// this.addStateTran(currentState, nextState, firedTran); + this.addStateTran(currentState, firedTran, nextState); + newTransitions++; + // TODO: (original) check that a variable was changed before creating a constraint + if(!firedTran.isLocal()){ + for(LPN lpn : firedTran.getDstLpnList()){ + //TODO: No need to generate constraint for the lpn where firedTran lives. + if (firedTran.getLpn().equals(lpn)) + continue; + Constraint c = new Constraint(currentState, nextState, firedTran, lpn); + lpn.getStateGraph().addConstraint(c); + } + } + } + if(!newStateFlag) + continue; + LpnTranList nextEnabledTransitions = getEnabled(nextState); + if (nextEnabledTransitions.isEmpty()) + continue; + Transition disabledTran = firedTran.disablingError(currentEnabledTransitions, nextEnabledTransitions); + if(disabledTran != null) { + System.out.println("Verification failed: " +disabledTran.getFullLabel() + " is disabled by " + + firedTran.getFullLabel()); + currentState.setFailure(); + return -1; + } + stStack.push(nextState); + tranStack.push(nextEnabledTransitions); + ptr++; + } + if (ptr == 0) { + break; + } + } + return newTransitions; + } + + /** + * Finds reachable states from the given state. + * Also generates new constraints from the state transitions. + * Synchronized version of constrFindSG(). Method is not synchronized, but uses synchronized methods + * @param baseState State to start from + * @return Number of new transitions. + */ + public int synchronizedConstrFindSG(final State baseState){ + boolean newStateFlag = false; + int ptr = 1; + int newTransitions = 0; + Stack stStack = new Stack(); + Stack tranStack = new Stack(); + LpnTranList currentEnabledTransitions = getEnabled(baseState); + + stStack.push(baseState); + tranStack.push(currentEnabledTransitions); + while (true){ + ptr--; + State currentState = stStack.pop(); + currentEnabledTransitions = tranStack.pop(); + + for (Transition firedTran : currentEnabledTransitions) { + State st = constrFire(firedTran,currentState); + State nextState = addState(st); + + newStateFlag = false; + if(nextState == st){ + newStateFlag = true; + addFrontierState(nextState); + } + + if(nextState != currentState){ + newTransitions++; + + if(!firedTran.isLocal()){ + // TODO: (original) check that a variable was changed before creating a constraint + for(LPN lpn : firedTran.getDstLpnList()){ + Constraint c = new Constraint(currentState, nextState, firedTran, lpn); + lpn.getStateGraph().synchronizedAddConstraint(c); + } + + } + } + + if(!newStateFlag) + continue; + + LpnTranList nextEnabledTransitions = getEnabled(nextState); + if (nextEnabledTransitions == null || nextEnabledTransitions.isEmpty()) { + continue; + } + +// currentEnabledTransitions = getEnabled(nexState); +// Transition disabledTran = firedTran.disablingError(currentEnabledTransitions, nextEnabledTransitions); +// if(disabledTran != null) { +// prDbg(10, "Verification failed: " +disabledTran.getFullLabel() + " is disabled by " + +// firedTran.getFullLabel()); +// +// currentState.setFailure(); +// return -1; +// } + + stStack.push(nextState); + tranStack.push(nextEnabledTransitions); + ptr++; + } + + if (ptr == 0) { + break; + } + } + + return newTransitions; + } + + public List getFrontierStateSet(){ + return this.frontierStateSet; + } + + public List getStateSet(){ + return this.stateSet; + } + + public void addFrontierState(State st){ + this.entryStateSet.add(st); + } + + public List getOldConstraintSet(){ + return this.oldConstraintSet; + } + + /** + * Adds constraint to the constraintSet. + * @param c - Constraint to be added. + * @return True if added, otherwise false. + */ + public boolean addConstraint(Constraint c){ + if(this.constraintSet.add(c)){ + this.frontierConstraintSet.add(c); + return true; + } + + return false; + } + + /** + * Adds constraint to the constraintSet. Synchronized version of addConstraint(). + * @param c - Constraint to be added. + * @return True if added, otherwise false. + */ + public synchronized boolean synchronizedAddConstraint(Constraint c){ + if(this.constraintSet.add(c)){ + this.frontierConstraintSet.add(c); + return true; + } + + return false; + } + + public List getNewConstraintSet(){ + return this.newConstraintSet; + } + + public void genConstraints(){ + oldConstraintSet.addAll(newConstraintSet); + newConstraintSet.clear(); + newConstraintSet.addAll(frontierConstraintSet); + frontierConstraintSet.clear(); + } + + + public void genFrontier(){ + this.stateSet.addAll(this.frontierStateSet); + this.frontierStateSet.clear(); + this.frontierStateSet.addAll(this.entryStateSet); + this.entryStateSet.clear(); + } + + public void setInitialState(State init){ + this.init = init; + } + + public State getInitialState(){ + return this.init; + } + + // Hao's method + public void draw(){ + String dotFile = Options.getDotPath(); + if(!dotFile.endsWith("/") && !dotFile.endsWith("\\")){ + String dirSlash = "/"; + if(System.getProperty("os.name").toLowerCase().contains("windows")) dirSlash = "\\"; + + dotFile = dotFile += dirSlash; + } + + dotFile += this.lpn.getLabel() + ".dot"; + PrintStream graph = null; + + try { + graph = new PrintStream(new FileOutputStream(dotFile)); + } catch (FileNotFoundException e1) { + e1.printStackTrace(); + return; + } + + graph.println("digraph SG{"); + //graph.println(" fixedsize=true"); + + int size = this.lpn.getAllOutputs().size() + this.lpn.getAllInputs().size() + this.lpn.getAllInternals().size(); + String[] variables = new String[size]; + + DualHashMap varIndexMap = this.lpn.getVarIndexMap(); + + int i; + for(i = 0; i < size; i++){ + variables[i] = varIndexMap.getKey(i); + } + + //for(State state : this.reachableSet.keySet()){ + for(int stateIdx = 0; stateIdx < this.reachSize(); stateIdx++) { + State state = this.getState(stateIdx); + String dotLabel = state.getIndex() + ": "; + int[] vector = state.getVariableVector(); + + for(i = 0; i < size; i++){ + dotLabel += variables[i]; + + if(vector[i] == 0) dotLabel += "'"; + + if(i < size-1) dotLabel += " "; + } + + int[] mark = state.getMarking(); + + dotLabel += "\\n"; + for(i = 0; i < mark.length; i++){ + if(i == 0) dotLabel += "["; + + dotLabel += mark[i]; + + if(i < mark.length - 1) + dotLabel += ", "; + else + dotLabel += "]"; + } + + String attributes = ""; + if(state == this.init) attributes += " peripheries=2"; + if(state.failure()) attributes += " style=filled fillcolor=\"red\""; + + graph.println(" " + state.getIndex() + "[shape=ellipse width=.3 height=.3 " + + "label=\"" + dotLabel + "\"" + attributes + "]"); + + + for(Entry stateTran : this.nextStateMap.get(state).entrySet()){ + State tailState = state; + State headState = stateTran.getValue(); + Transition lpnTran = stateTran.getKey(); + + String edgeLabel = lpnTran.getLabel() + ": "; + int[] headVector = headState.getVariableVector(); + int[] tailVector = tailState.getVariableVector(); + + for(i = 0; i < size; i++){ + if(headVector[i] != tailVector[i]){ + if(headVector[i] == 0){ + edgeLabel += variables[i]; + edgeLabel += "-"; + } + else{ + edgeLabel += variables[i]; + edgeLabel += "+"; + } + } + } + + graph.println(" " + tailState.getIndex() + " -> " + headState.getIndex() + "[label=\"" + edgeLabel + "\"]"); + } + } + + graph.println("}"); + graph.close(); + } + + /** + * Return the enabled transitions in the state with index 'stateIdx'. + * @param stateIdx + * @return + */ + public LpnTranList getEnabled(int stateIdx) { + State curState = this.getState(stateIdx); + return this.getEnabled(curState); + } + /** + * Return the set of all LPN transitions that are enabled in the given state. + * @param curState + * @return + */ + public LpnTranList getEnabled(State curState) { + if (curState == null) { + throw new NullPointerException(); + } + + if(enabledSetTbl.containsKey(curState) == true){ + // TODO: need to return a clone? + return enabledSetTbl.get(curState).clone(); + } + + LpnTranList curEnabled = new LpnTranList(); + for (Transition tran : this.lpn.getAllTransitions()) { + if (isEnabled(tran,curState)) { + if(tran.isLocal()==true) + curEnabled.addLast(tran); + else + curEnabled.addFirst(tran); + } + } + this.enabledSetTbl.put(curState, curEnabled); + return curEnabled; + } + + /** + * Return the set of all enabled local transitions in the current local state. The enabled transitions + * are read from the tranVector in current state. + * @param curState + * @return + */ + public static LpnTranList getEnabledFromTranVector(State curState) { + if (curState == null) { + throw new NullPointerException(); + } + LpnTranList curEnabled = curState.getEnabledTransitions(); + return curEnabled; + } + +// protected void printEnabledSetTblToDebugFile() { +// System.out.println("******* enabledSetTbl**********"); +// for (State s : enabledSetTbl.keySet()) { +// System.out.print("S" + s.getIndex() + " -> "); +// printTransitionSet(enabledSetTbl.get(s), ""); +// } +// } + + protected static void printTransitionSet(LpnTranList transitionSet, String setName) { + if (!setName.isEmpty()) + System.out.println(setName + " : "); + if (transitionSet.isEmpty()) { + System.out.println("empty"); + } + else { + for (Transition tran : transitionSet) { + System.out.print(tran.getFullLabel() + ", "); + } + System.out.println(""); + } + } + + + private boolean isEnabled(Transition tran, State curState) { + int[] varValuesVector = curState.getVariableVector(); + String tranName = tran.getLabel(); + int tranIndex = tran.getIndex(); + if (Options.getDebugMode()) { +// System.out.println("Checking " + tran); + } + if (this.lpn.getEnablingTree(tranName) != null + && this.lpn.getEnablingTree(tranName).evaluateExpr(this.lpn.getAllVarsWithValuesAsString(varValuesVector)) == 0.0 + && !(tran.isPersistent() && curState.getTranVector()[tranIndex])) { + if (Options.getDebugMode()) { +// System.out.println(tran.getName() + " " + "Enabling condition is false"); + } + return false; + } + if (this.lpn.getTransitionRateTree(tranName) != null + && this.lpn.getTransitionRateTree(tranName).evaluateExpr(this.lpn.getAllVarsWithValuesAsString(varValuesVector)) == 0.0) { + if (Options.getDebugMode()) { +// System.out.println("Rate is zero"); + } + return false; + } + if (this.lpn.getPreset(tranName) != null && this.lpn.getPreset(tranName).length != 0) { + int[] curMarking = curState.getMarking(); + for (int place : this.lpn.getPresetIndex(tranName)) { + if (curMarking[place]==0) { + if (Options.getDebugMode()) { +// System.out.println(tran.getName() + " " + "Missing a preset token"); + } + return false; + } + } + // if a transition is enabled and it is not recorded in the enabled transition vector + curState.getTranVector()[tranIndex] = true; + } + return true; + } + + public int reachSize() { + if(this.stateCache == null){ + return this.stateSet.size(); + } + + return this.stateCache.size(); + } + + public static boolean stateOnStack(State curState, HashSet stateStack) { + boolean isStateOnStack = false; + for (PrjState prjState : stateStack) { + State[] stateArray = prjState.toStateArray(); + for (State s : stateArray) { + if (s == curState) { + isStateOnStack = true; + break; + } + } + if (isStateOnStack) + break; + } + return isStateOnStack; + } + + /** + * Add the module state mState to the local cache, and also add its local portion to + * the local portion cache, and build the mapping between the mState and lState for fast lookup + * in the future. + * @param mState + * @return State + */ + public State addState(State mState) { + State cachedState = this.stateCache.add(mState); + State lState = this.state2LocalMap.get(cachedState); + if(lState == null) { + lState = cachedState.getLocalState(); + //lState = this.localStateCache.add(lState); + this.state2LocalMap.put(cachedState, lState); + } + return cachedState; + } + + /* + * Get the local portion of mState from the cache.. + */ + public State getLocalState(State mState) { + return this.state2LocalMap.get(mState); + } + + public State getState(int stateIdx) { + return this.stateCache.get(stateIdx); + } + + public void addStateTran(State curSt, Transition firedTran, State nextSt) { + HashMap nextMap = this.nextStateMap.get(curSt); + if(nextMap == null) { + nextMap = new HashMap(); + nextMap.put(firedTran, nextSt); + this.nextStateMap.put(curSt, nextMap); + } + else { + nextMap.put(firedTran, nextSt); + } +// if (Options.getDebugMode()) +// printNextStateForGivenState(curSt, "StateGraph.java -> addStateTran(State, Transition, State)"); + } + + public State getNextState(State curSt, Transition firedTran) { + HashMap nextMap = this.nextStateMap.get(curSt); + if(nextMap == null) + return null; + return nextMap.get(firedTran); + } + + // Hao's method + public Set> getOutgoingTrans(State currentState){ + HashMap tranMap = this.nextStateMap.get(currentState); + if(tranMap == null){ + return emptySet; + } + return tranMap.entrySet(); + } + + public int numConstraints(){ + if(this.constraintSet == null){ + return this.oldConstraintSet.size(); + } + + return this.constraintSet.size(); + } + + public void clear(){ + this.constraintSet.clear(); + this.frontierConstraintSet.clear(); + this.newConstraintSet.clear(); + this.frontierStateSet.clear(); + this.entryStateSet.clear(); + + this.constraintSet = null; + this.frontierConstraintSet = null; + this.newConstraintSet = null; + this.frontierStateSet = null; + this.entryStateSet = null; + this.stateCache = null; + } + + public State genInitialState() { + // create initial vector: vector for variable initial values. + int size = this.lpn.getVarIndexMap().size(); + int[] initVariableVector = new int[size]; + for(int i = 0; i < size; i++) { + String var = this.lpn.getVarIndexMap().getKey(i); + int val = this.lpn.getInitVariableVector(var); + initVariableVector[i] = val; + } + // Initial state can contain immediate transitions. + this.init = new State(this.lpn, this.lpn.getInitialMarkingsArray(), initVariableVector, genInitTranVector(initVariableVector)); + return this.init; + } + + /** + * If an immediate transition is enabled in the current state, + * returns the first enabled immediate transition of curState, otherwise return null. + * @param curState + * @return + */ + public static Transition getEnabledImmediateTran(State curState) { + Transition enabledImmTran = null; + for (Transition enabledTran : curState.getEnabledTransitions()) { + if (enabledTran.getDelay() == null) { + enabledImmTran = enabledTran; + break; + } + } + return enabledImmTran; + } + + /** + * Fire a transition on a state array, find new local states, and return the new state array formed by the new local states. + * @param firedTran + * @param curLpnArray + * @param curStateArray + * @param curLpnIndex + * @return + */ + + public State[] fire(final StateGraph[] curSgArray, final int[] curStateIdxArray, Transition firedTran) { + State[] stateArray = new State[curSgArray.length]; + for(int i = 0; i < curSgArray.length; i++) + stateArray[i] = curSgArray[i].getState(curStateIdxArray[i]); + + return this.fire(curSgArray, stateArray, firedTran); + } + + /** + * This method is called by untimed search_dfs(StateGraph[], State[]). + * @param curSgArray + * @param curStateArray + * @param firedTran + * @return + */ + public State[] fire(final StateGraph[] curSgArray, final State[] curStateArray, Transition firedTran){ +// HashMap continuousValues, Zone z) { +// public State[] fire(final StateGraph[] curSgArray, final State[] curStateArray, Transition firedTran, +// ArrayList> newAssignValues, Zone z) { +// public State[] fire(final StateGraph[] curSgArray, final State[] curStateArray, Transition firedTran, +// ArrayList> newAssignValues, Zone z) { + + int thisLpnIndex = this.getLpn().getLpnIndex(); + State[] nextStateArray = curStateArray.clone(); + + State curState = curStateArray[thisLpnIndex]; +// State nextState = this.fire(curSgArray[thisLpnIndex], curState, firedTran, continuousValues, z); + +// State nextState = this.fire(curSgArray[thisLpnIndex], curState, firedTran, newAssignValues, z); + State nextState = this.fire(curSgArray[thisLpnIndex], curState, firedTran); + + //int[] nextVector = nextState.getVector(); + //int[] curVector = curState.getVector(); + + // TODO: (future) assertions in our LPN? + /* + for(Expression e : assertions){ + if(e.evaluate(nextVector) == 0){ + System.err.println("Assertion " + e.toString() + " failed in LPN transition " + this.lpn.getLabel() + ":" + this.label); + System.exit(1); + } + } + */ + nextStateArray[thisLpnIndex] = nextState; + if(firedTran.isLocal()==true) { +// nextStateArray[thisLpnIndex] = curSgArray[thisLpnIndex].addState(nextState); + return nextStateArray; + } + HashMap vvSet = new HashMap(); + vvSet = this.lpn.getAllVarsWithValuesAsInt(nextState.getVariableVector()); + // Update other local states with the new values generated for the shared variables. + //nextStateArray[this.lpn.getIndex()] = nextState; +// if (!firedTran.getDstLpnList().contains(this.lpn)) +// firedTran.getDstLpnList().add(this.lpn); + for(LPN curLPN : firedTran.getDstLpnList()) { + int curIdx = curLPN.getLpnIndex(); + State newState = curSgArray[curIdx].getNextState(curStateArray[curIdx], firedTran); + if(newState != null) { + nextStateArray[curIdx] = newState; + } + else { + State newOther = curStateArray[curIdx].update(curSgArray[curIdx], vvSet, curSgArray[curIdx].getLpn().getVarIndexMap()); + if (newOther == null) + nextStateArray[curIdx] = curStateArray[curIdx]; + else { + State cachedOther = curSgArray[curIdx].addState(newOther); + //nextStateArray[curIdx] = newOther; + nextStateArray[curIdx] = cachedOther; +// System.out.println("ADDING TO " + curIdx + ":\n" + curStateArray[curIdx].getIndex() + ":\n" + +// curStateArray[curIdx].print() + firedTran.getName() + "\n" + +// cachedOther.getIndex() + ":\n" + cachedOther.print()); + curSgArray[curIdx].addStateTran(curStateArray[curIdx], firedTran, cachedOther); + if (Options.getDebugMode()) { + String location = "StateGraph.java, fire(StateGraph[], State[], Transition)"; + printNextStateForGivenState(curStateArray[curIdx], location); + } + } + } + } + return nextStateArray; + } + + + /** + * This method is used by untimed search_dfs(StateGraph[], State[]). + * @param thisSg + * @param curState + * @param firedTran + * @return + */ + public State fire(final StateGraph thisSg, final State curState, Transition firedTran){ +// HashMap continuousValues, Zone z) { +// public State fire(final StateGraph thisSg, final State curState, Transition firedTran, +// ArrayList> newAssignValues, Zone z) { +// public State fire(final StateGraph thisSg, final State curState, Transition firedTran, +// ArrayList> newAssignValues, Zone z) { + + // Search for and return cached next state first. +// if(this.nextStateMap.containsKey(curState) == true) +// return (State)this.nextStateMap.get(curState); + + State nextState = thisSg.getNextState(curState, firedTran); + + if(Options.getTimingAnalysisFlag()){ + // This effectively turns off the caching done by + // thisSg.getNextState. The caching takes the current state and transition and + // outputs the next state if it has been seen before. The problem with this + // is that it is agnostic to timing information while the state itself is not + // due to having the boolean variables for the inequalities. Thus, it is possible + // to have the same current state and transition result in different next states + // based on how the continuous portion of the state effects the boolean inequality + // variables. + nextState = null; + } + + if(nextState != null) + return nextState; + // If no cached next state exists, do regular firing. + // Marking update + int[] curOldMarking = curState.getMarking(); + int[] curNewMarking = null; + if(firedTran.getPreset().length==0 && firedTran.getPostset().length==0) + curNewMarking = curOldMarking; + else { + curNewMarking = new int[curOldMarking.length]; + curNewMarking = curOldMarking.clone(); + for (int prep : this.lpn.getPresetIndex(firedTran.getLabel())) { + curNewMarking[prep]=0; + } + for (int postp : this.lpn.getPostsetIndex(firedTran.getLabel())) { + curNewMarking[postp]=1; + } + } + + // State vector update + int[] newVariableVector = curState.getVariableVector().clone(); + int[] curVector = curState.getVariableVector(); + HashMap currentValuesAsString = this.lpn.getAllVarsWithValuesAsString(curVector); + for (String key : currentValuesAsString.keySet()) { + if (this.lpn.getBoolAssignTree(firedTran.getLabel(), key) != null) { + int newValue = (int)this.lpn.getBoolAssignTree(firedTran.getLabel(), key).evaluateExpr(currentValuesAsString); + newVariableVector[this.lpn.getVarIndexMap().get(key)] = newValue; + } + + if (this.lpn.getIntAssignTree(firedTran.getLabel(), key) != null) { + int newValue = (int)this.lpn.getIntAssignTree(firedTran.getLabel(), key).evaluateExpr(currentValuesAsString); + newVariableVector[this.lpn.getVarIndexMap().get(key)] = newValue; + } + } + +// // Update rates +// final int OLD_ZERO = 0; // Case 0 in description. +//// final int NEW_NON_ZERO = 1; // Case 1 in description. +//// final int NEW_ZERO = 2; // Case 2 in description. +//// final int OLD_NON_ZERO = 3; // Case 3 in description. +//// newAssignValues.add(new HashMap()); +//// newAssignValues.add(new HashMap()); +//// newAssignValues.add(new HashMap()); +//// newAssignValues.add(new HashMap()); +// +// final int NEW_NON_ZERO = 1; // Case 1 in description. +// final int NEW_ZERO = 2; // Case 2 in description. +// final int OLD_NON_ZERO = 3; // Cade 3 in description. +// if(Options.getTimingAnalysisFlag()){ +// newAssignValues.add(new HashMap()); +// newAssignValues.add(new HashMap()); +// newAssignValues.add(new HashMap()); +// newAssignValues.add(new HashMap()); +// } +// +// for(String key : this.lpn.getContVars()){ +// +// // Get the pairing. +// int lpnIndex = this.lpn.getLpnIndex(); +// int contVarIndex = this.lpn.getContVarIndex(key); +// +// // Package up the indecies. +// LPNContinuousPair contVar = new LPNContinuousPair(lpnIndex, contVarIndex); +// +// //Integer newRate = null; +// IntervalPair newRate = null; +// IntervalPair newValue= null; +// +// // Check if there is a new rate assignment. +// if(this.lpn.getRateAssignTree(firedTran.getName(), key) != null){ +// // Get the new value. +// //IntervalPair newIntervalRate = this.lpn.getRateAssignTree(firedTran.getName(), key) +// //.evaluateExprBound(this.lpn.getAllVarsWithValuesAsString(curVector), z, null); +// newRate = this.lpn.getRateAssignTree(firedTran.getName(), key) +// .evaluateExprBound(currentValuesAsString, z, null); +// +//// // Get the pairing. +//// int lpnIndex = this.lpn.getLpnIndex(); +//// int contVarIndex = this.lpn.getContVarIndex(key); +//// +//// // Package up the indecies. +//// LPNContinuousPair contVar = new LPNContinuousPair(lpnIndex, contVarIndex); +// +// // Keep the current rate. +// //newRate = newIntervalRate.get_LowerBound(); +// +// //contVar.setCurrentRate(newIntervalRate.get_LowerBound()); +// contVar.setCurrentRate(newRate.get_LowerBound()); +// +//// continuousValues.put(contVar, new IntervalPair(z.getDbmEntryByPair(contVar, LPNTransitionPair.ZERO_TIMER_PAIR), +//// z.getDbmEntryByPair(LPNTransitionPair.ZERO_TIMER_PAIR, contVar))); +// +//// // Check if the new assignment gives rate zero. +//// boolean newRateZero = newRate == 0; +//// // Check if the variable was already rate zero. +//// boolean oldRateZero = z.getCurrentRate(contVar) == 0; +//// +//// // Put the new value in the appropriate set. +//// if(oldRateZero){ +//// if(newRateZero){ +//// // Old rate is zero and the new rate is zero. +//// newAssignValues.get(OLD_ZERO).put(contVar, newValue); +//// } +//// else{ +//// // Old rate is zero and the new rate is non-zero. +//// newAssignValues.get(NEW_NON_ZERO).put(contVar, newValue); +//// } +//// } +//// else{ +//// if(newRateZero){ +//// // Old rate is non-zero and the new rate is zero. +//// newAssignValues.get(NEW_ZERO).put(contVar, newValue); +//// } +//// else{ +//// // Old rate is non-zero and the new rate is non-zero. +//// newAssignValues.get(OLD_NON_ZERO).put(contVar, newValue); +//// } +//// } +// } +// //} +// +// // Update continuous variables. +// //for(String key : this.lpn.getContVars()){ +// // Get the new assignments on the continuous variables and update inequalities. +// if (this.lpn.getContAssignTree(firedTran.getName(), key) != null) { +//// int newValue = (int)this.lpn.getContAssignTree(firedTran.getName(), key).evaluateExpr(this.lpn.getAllVarsWithValuesAsString(curVector)); +//// newVectorArray[this.lpn.getVarIndexMap().get(key)] = newValue; +// +// // Get the new value. +// newValue = this.lpn.getContAssignTree(firedTran.getName(), key) +// //.evaluateExprBound(this.lpn.getAllVarsWithValuesAsString(curVector), z, null); +// .evaluateExprBound(currentValuesAsString, z, null); +// +//// // Get the pairing. +//// int lpnIndex = this.lpn.getLpnIndex(); +//// int contVarIndex = this.lpn.getContVarIndex(key); +//// +//// // Package up the indecies. +//// LPNContinuousPair contVar = new LPNContinuousPair(lpnIndex, contVarIndex); +// +// if(newRate == null){ +// // Keep the current rate. +// contVar.setCurrentRate(z.getCurrentRate(contVar)); +// } +// +// +//// continuousValues.put(contVar, newValue); +// +// // Get each inequality that involves the continuous variable. +// ArrayList inequalities = this.lpn.getContVar(contVarIndex).getInequalities(); +// +// // Update the inequalities. +// for(InequalityVariable ineq : inequalities){ +// int ineqIndex = this.lpn.getVarIndexMap().get(ineq.getName()); +// +// +// HashMap continuousValues = new HashMap(); +// continuousValues.putAll(newAssignValues.get(OLD_ZERO)); +// continuousValues.putAll(newAssignValues.get(NEW_NON_ZERO)); +// continuousValues.putAll(newAssignValues.get(NEW_ZERO)); +// continuousValues.putAll(newAssignValues.get(OLD_NON_ZERO)); +// +// +// newVectorArray[ineqIndex] = ineq.evaluate(newVectorArray, z, continuousValues); +// } +// } +// +// +// // If the value did not get assigned, put in the old value. +// if(newValue == null){ +// newValue = z.getContinuousBounds(contVar); +// } +// +// // Check if the new assignment gives rate zero. +// //boolean newRateZero = newRate == 0; +// boolean newRateZero = newRate.singleValue() ? newRate.get_LowerBound() == 0 : false; +// // Check if the variable was already rate zero. +// boolean oldRateZero = z.getCurrentRate(contVar) == 0; +// +// // Put the new value in the appropriate set. +// if(oldRateZero){ +// if(newRateZero){ +// // Old rate is zero and the new rate is zero. +// newAssignValues.get(OLD_ZERO).put(new LPNContAndRate(contVar, newRate), newValue); +// } +// else{ +// // Old rate is zero and the new rate is non-zero. +// newAssignValues.get(NEW_NON_ZERO).put(new LPNContAndRate(contVar, newRate), newValue); +// } +// } +// else{ +// if(newRateZero){ +// // Old rate is non-zero and the new rate is zero. +// newAssignValues.get(NEW_ZERO).put(new LPNContAndRate(contVar, newRate), newValue); +// } +// else{ +// // Old rate is non-zero and the new rate is non-zero. +// newAssignValues.get(OLD_NON_ZERO).put(new LPNContAndRate(contVar, newRate), newValue); +// } +// } +// +// } + + /* + for (VarExpr s : firedTran.getAssignments()) { + int newValue = (int) s.getExpr().evaluate(curVector); + newVectorArray[s.getVar().getIndex(curVector)] = newValue; + } + */ + // Enabled transition vector update + boolean[] newTranVector = updateTranVector(curState, curNewMarking, newVariableVector, firedTran); + State newState = thisSg.addState(new State(this.lpn, curNewMarking, newVariableVector, newTranVector)); + + // TODO: (future) assertions in our LPN? + /* + int[] newVector = newState.getVector(); + for(Expression e : assertions){ + if(e.evaluate(newVector) == 0){ + System.err.println("Assertion " + e.toString() + " failed in LPN transition " + this.lpn.getLabel() + ":" + this.label); + System.exit(1); + } + } + */ + thisSg.addStateTran(curState, firedTran, newState); + if (Options.getDebugMode()) { + String location = "StateGraph.java, fire(StateGraph, State, Transition)"; + thisSg.printNextStateForGivenState(curState, location); + } + return newState; + } + + public boolean[] updateTranVector(State state, + int[] newMarking, int[] newVariableVector, Transition firedTran) { + boolean[] tranVectorAfterFiring = state.getTranVector().clone(); + // Disable the fired transition and all of its conflicting transitions. + if (firedTran != null) { + tranVectorAfterFiring[firedTran.getIndex()] = false; + for (Integer curConflictingTranIndex : firedTran.getConflictSetTransIndices()) { + tranVectorAfterFiring[curConflictingTranIndex] = false; + } + } + // find newly enabled transition(s) based on the updated markings and variables + for (Transition tran : this.lpn.getAllTransitions()) { + boolean needToUpdate = true; + String tranName = tran.getLabel(); + int tranIndex = tran.getIndex(); + if (Options.getDebugMode()) { +// System.out.println("Checking " + tranName); + } + if (this.lpn.getEnablingTree(tranName) != null + && this.lpn.getEnablingTree(tranName).evaluateExpr(this.lpn.getAllVarsWithValuesAsString(newVariableVector)) == 0.0) { + if (Options.getDebugMode()) { +// System.out.println(tran.getName() + " " + "Enabling condition is false"); + } + if (tranVectorAfterFiring[tranIndex] && !tran.isPersistent()) + tranVectorAfterFiring[tranIndex] = false; + continue; + } + if (this.lpn.getTransitionRateTree(tranName) != null + && this.lpn.getTransitionRateTree(tranName).evaluateExpr(this.lpn.getAllVarsWithValuesAsString(newVariableVector)) == 0.0) { + if (Options.getDebugMode()) { +// System.out.println("Rate is zero"); + } + if (tranVectorAfterFiring[tranIndex]) + tranVectorAfterFiring[tranIndex] = false; + continue; + } + if (this.lpn.getPreset(tranName) != null && this.lpn.getPreset(tranName).length != 0) { + for (int place : this.lpn.getPresetIndex(tranName)) { + if (newMarking[place]==0) { + if (Options.getDebugMode()) { +// System.out.println(tran.getName() + " " + "Missing a preset token"); + } + needToUpdate = false; + if (tranVectorAfterFiring[tranIndex]) + tranVectorAfterFiring[tranIndex] = false; + break; + } + } + } + if (needToUpdate) { + tranVectorAfterFiring[tranIndex] = true; + if (Options.getDebugMode()) { +// System.out.println(tran.getName() + " is Enabled."); + } + } + } + return tranVectorAfterFiring; + } + + /** + * Updates the transition vector. + * @param enabledTranBeforeFiring + * The enabling before the transition firing. + * @param newMarking + * The new marking to check for transitions with. + * @param newVectorArray + * The new values of the boolean variables. + * @param firedTran + * The transition that fire. + * @param newlyEnabled + * A list to capture the newly enabled transitions. + * @return + * The newly enabled transitions. + */ + public boolean[] updateTranVector(boolean[] enabledTranBeforeFiring, + int[] newMarking, int[] newVectorArray, Transition firedTran, HashSet newlyEnabled) { + boolean[] enabledTranAfterFiring = enabledTranBeforeFiring.clone(); + // Disable fired transition + if (firedTran != null) { + enabledTranAfterFiring[firedTran.getIndex()] = false; + for (Integer curConflictingTranIndex : firedTran.getConflictSetTransIndices()) { + enabledTranAfterFiring[curConflictingTranIndex] = false; + } + } + // find newly enabled transition(s) based on the updated markings and variables + if (Options.getDebugMode()) + System.out.println("Finding newly enabled transitions at updateEnabledTranVector."); + for (Transition tran : this.lpn.getAllTransitions()) { + boolean needToUpdate = true; + String tranName = tran.getLabel(); + int tranIndex = tran.getIndex(); + if (Options.getDebugMode()) + System.out.println("Checking " + tranName); + if (this.lpn.getEnablingTree(tranName) != null + && this.lpn.getEnablingTree(tranName).evaluateExpr(this.lpn.getAllVarsWithValuesAsString(newVectorArray)) == 0.0) { + if (Options.getDebugMode()) + System.out.println(tran.getLabel() + " " + "Enabling condition is false"); + if (enabledTranAfterFiring[tranIndex] && !tran.isPersistent()) + enabledTranAfterFiring[tranIndex] = false; + continue; + } + if (this.lpn.getTransitionRateTree(tranName) != null + && this.lpn.getTransitionRateTree(tranName).evaluateExpr(this.lpn.getAllVarsWithValuesAsString(newVectorArray)) == 0.0) { + if (Options.getDebugMode()) + System.out.println("Rate is zero"); + continue; + } + if (this.lpn.getPreset(tranName) != null && this.lpn.getPreset(tranName).length != 0) { + for (int place : this.lpn.getPresetIndex(tranName)) { + if (newMarking[place]==0) { + if (Options.getDebugMode()) + System.out.println(tran.getLabel() + " " + "Missing a preset token"); + needToUpdate = false; + break; + } + } + } + if (needToUpdate) { + // if a transition is enabled and it is not recorded in the enabled transition vector + enabledTranAfterFiring[tranIndex] = true; + if (Options.getDebugMode()) + System.out.println(tran.getLabel() + " is Enabled."); + } + + if(newlyEnabled != null && enabledTranAfterFiring[tranIndex] && !enabledTranBeforeFiring[tranIndex]){ + newlyEnabled.add(new LPNTransitionPair(tran.getLpn().getLpnIndex(), tranIndex)); + } + } + return enabledTranAfterFiring; + } + + public State constrFire(Transition firedTran, final State curState) { + // Hao's original marking update. +// // Marking update +// int[] curOldMarking = curState.getMarking(); +// int[] curNewMarking = null; +// if(firedTran.getPreset().length==0 && firedTran.getPostset().length==0){ +// curNewMarking = curOldMarking; +// } +// else { +// curNewMarking = new int[curOldMarking.length - firedTran.getPreset().length + firedTran.getPostset().length]; +// int index = 0; +// for (int i : curOldMarking) { +// boolean existed = false; +// for (int prep : this.lpn.getPresetIndex(firedTran.getName())) { +// if (i == prep) { +// existed = true; +// break; +// } +// else if(prep > i){ +// break; +// } +// } +// +// if (existed == false) { +// curNewMarking[index] = i; +// index++; +// } +// } +// +// for (int postp : this.lpn.getPostsetIndex(firedTran.getName())) { +// curNewMarking[index] = postp; +// index++; +// } +// } + + int[] curOldMarking = curState.getMarking(); + int[] curNewMarking = null; + if(firedTran.getPreset().length==0 && firedTran.getPostset().length==0) + curNewMarking = curOldMarking; + else { + curNewMarking = new int[curOldMarking.length]; + curNewMarking = curOldMarking.clone(); + for (int prep : this.lpn.getPresetIndex(firedTran.getLabel())) { + curNewMarking[prep]=0; + } + for (int postp : this.lpn.getPostsetIndex(firedTran.getLabel())) { + curNewMarking[postp]=1; + } + } + + // State vector update + int[] oldVector = curState.getVariableVector(); + int size = oldVector.length; + int[] newVectorArray = new int[size]; + System.arraycopy(oldVector, 0, newVectorArray, 0, size); + + int[] curVector = curState.getVariableVector(); + for (String key : this.lpn.getAllVarsWithValuesAsString(curVector).keySet()) { + if (this.lpn.getBoolAssignTree(firedTran.getLabel(), key) != null) { + int newValue = (int)this.lpn.getBoolAssignTree(firedTran.getLabel(), key).evaluateExpr(this.lpn.getAllVarsWithValuesAsString(curVector)); + newVectorArray[this.lpn.getVarIndexMap().get(key)] = newValue; + } + if (this.lpn.getIntAssignTree(firedTran.getLabel(), key) != null) { + int newValue = (int)this.lpn.getIntAssignTree(firedTran.getLabel(), key).evaluateExpr(this.lpn.getAllVarsWithValuesAsString(curVector)); + newVectorArray[this.lpn.getVarIndexMap().get(key)] = newValue; + } + } + // Enabled transition vector update + /* Hao's code + //boolean[] newEnabledTranArray = curState.getTranVector(); + //newEnabledTranArray[firedTran.getIndex()] = false; + //State newState = new State(this.lpn, curNewMarking, newVectorArray, newEnabledTranArray); + */ + boolean[] newEnabledTranVector = updateTranVector(curState, curNewMarking, newVectorArray, firedTran); + State newState = new State(this.lpn, curNewMarking, newVectorArray, newEnabledTranVector); + + // TODO: (future) assertions in our LPN? + /* + int[] newVector = newState.getVector(); + for(Expression e : assertions){ + if(e.evaluate(newVector) == 0){ + System.err.println("Assertion " + e.toString() + " failed in LPN transition " + this.lpn.getLabel() + ":" + this.label); + System.exit(1); + } + } + */ + return newState; + } + + public void drawLocalStateGraph() { + try { + String graphFileName = null; + if ( Options.getTimingAnalysisType() == "off") { + if (Options.getPOR().toLowerCase().equals("off")) { + graphFileName = Options.getPrjSgPath() + separator + getLpn().getLabel() + "_local_full_sg.dot"; + } + else { + graphFileName = Options.getPrjSgPath() + separator + getLpn().getLabel() + "_POR_"+ Options.getCycleClosingMthd() + "_local_sg.dot"; + } + } else { + // TODO: Need to add separator here? + graphFileName = Options.getPrjSgPath() + getLpn().getLabel() + "_sg.dot"; + } + int size = this.lpn.getVarIndexMap().size(); + String varNames = ""; + for(int i = 0; i < size; i++) { + varNames = varNames + ", " + this.lpn.getVarIndexMap().getKey(i); + } + varNames = varNames.replaceFirst(", ", ""); + BufferedWriter out = new BufferedWriter(new FileWriter(graphFileName)); + out.write("digraph G {\n"); + out.write("Inits [shape=plaintext, label=\"<" + varNames + ">\"]\n"); + for (State curState : nextStateMap.keySet()) { + String markings = intArrayToString("markings", curState); + String vars = intArrayToString("vars", curState); + String enabledTrans = boolArrayToString("enabledTrans", curState); + String curStateName = "S" + curState.getIndex(); + out.write(curStateName + "[shape=\"ellipse\",label=\"" + curStateName + "\\n<"+vars+">" + "\\n<"+enabledTrans+">" + "\\n<"+markings+">" + "\"]\n"); + } + + for (State curState : nextStateMap.keySet()) { + HashMap stateTransitionPair = nextStateMap.get(curState); + for (Transition curTran : stateTransitionPair.keySet()) { + String curStateName = "S" + curState.getIndex(); + String nextStateName = "S" + stateTransitionPair.get(curTran).getIndex(); + String curTranName = curTran.getLabel(); + if (curTran.isFail() && !curTran.isPersistent()) + out.write(curStateName + " -> " + nextStateName + " [label=\"" + curTranName + "\", fontcolor=red]\n"); + else if (!curTran.isFail() && curTran.isPersistent()) + out.write(curStateName + " -> " + nextStateName + " [label=\"" + curTranName + "\", fontcolor=blue]\n"); + else if (curTran.isFail() && curTran.isPersistent()) + out.write(curStateName + " -> " + nextStateName + " [label=\"" + curTranName + "\", fontcolor=purple]\n"); + else + out.write(curStateName + " -> " + nextStateName + " [label=\"" + curTranName + "\"]\n"); + } + } + out.write("}"); + out.close(); + } + catch (Exception e) { + e.printStackTrace(); + System.err.println("Error producing local state graph as dot file."); + } + } + + protected static String intArrayToString(String type, State curState) { + String arrayStr = ""; + if (type.equals("markings")) { + for (int i=0; i< curState.getMarking().length; i++) { + if (curState.getMarking()[i] == 1) { + arrayStr = arrayStr + curState.getLpn().getPlaceList()[i] + ","; + } +// String tranName = curState.getLpn().getAllTransitions()[i].getName(); +// if (curState.getTranVector()[i]) +// System.out.println(tranName + " " + "Enabled"); +// else +// System.out.println(tranName + " " + "Not Enabled"); + } + arrayStr = arrayStr.substring(0, arrayStr.lastIndexOf(",")); + } + else if (type.equals("vars")) { + for (int i=0; i< curState.getVariableVector().length; i++) { + arrayStr = arrayStr + curState.getVariableVector()[i] + ","; + } + if (arrayStr.contains(",")) + arrayStr = arrayStr.substring(0, arrayStr.lastIndexOf(",")); + } + return arrayStr; + } + + protected static String boolArrayToString(String type, State curState) { + String arrayStr = ""; + if (type.equals("enabledTrans")) { + for (int i=0; i< curState.getTranVector().length; i++) { + if (curState.getTranVector()[i]) { + arrayStr = arrayStr + curState.getLpn().getAllTransitions()[i].getLabel() + ","; + } + } + if (arrayStr != "") + arrayStr = arrayStr.substring(0, arrayStr.lastIndexOf(",")); + } + return arrayStr; + } + +// private void printTransitionSet(LpnTranList transitionSet, String setName) { +// if (!setName.isEmpty()) +// System.out.print(setName + " "); +// if (transitionSet.isEmpty()) { +// System.out.println("empty"); +// } +// else { +// for (Iterator curTranIter = transitionSet.iterator(); curTranIter.hasNext();) { +// Transition tranInDisable = curTranIter.next(); +// System.out.print(tranInDisable.getName() + " "); +// } +// System.out.print("\n"); +// } +// } + +// private static void printAmpleSet(LpnTranList transitionSet, String setName) { +// if (!setName.isEmpty()) +// System.out.print(setName + " "); +// if (transitionSet.isEmpty()) { +// System.out.println("empty"); +// } +// else { +// for (Iterator curTranIter = transitionSet.iterator(); curTranIter.hasNext();) { +// Transition tranInDisable = curTranIter.next(); +// System.out.print(tranInDisable.getName() + " "); +// } +// System.out.print("\n"); +// } +// } + +// public HashMap copyEnabledSetTbl() { +// HashMap copyEnabledSetTbl = new HashMap(); +// for (State s : enabledSetTbl.keySet()) { +// LpnTranList tranList = enabledSetTbl.get(s).clone(); +// copyEnabledSetTbl.put(s.clone(), tranList); +// } +// return copyEnabledSetTbl; +// } + + public HashMap getEnabledSetTbl() { + return this.enabledSetTbl; + } + + public HashMap> getNextStateMap() { + return this.nextStateMap; + } + + /** + * Fires a transition for the timed code. + * @param curSgArray + * The current information on the all local states. + * @param currentPrjState + * The current state. + * @param firedTran + * The transition to fire. + * @return + * The new states. + */ + public TimedPrjState fire(final StateGraph[] curSgArray, + final PrjState currentPrjState, Transition firedTran){ + + TimedPrjState currentTimedPrjState; + + // Check that this is a timed state. + if(currentPrjState instanceof TimedPrjState){ + currentTimedPrjState = (TimedPrjState) currentPrjState; + } + else{ + throw new IllegalArgumentException("Attempted to use the " + + "fire(StateGraph[],PrjState,Transition)" + + "without a TimedPrjState stored in the PrjState " + + "variable. This method is meant for TimedPrjStates."); + } + + // Extract relevant information from the current project state. + State[] curStateArray = currentTimedPrjState.toStateArray(); +// Zone[] currentZones = currentTimedPrjState.toZoneArray(); + Equivalence[] currentZones = currentTimedPrjState.toZoneArray(); + + +// Zone[] newZones = new Zone[1]; + Equivalence[] newZones = new Equivalence[1]; + + /* + * This ArrayList contains four separate maps that store the + * rate and continuous variables assignments. + */ + + // Get the new un-timed local states. + State[] newStates = fire(curSgArray, curStateArray, firedTran); + + + +// ArrayList> newAssignValues = +// updateContinuousState(currentTimedPrjState.get_zones()[0], curStateArray, newStates, firedTran); + +// ArrayList newAssignValues = +// updateContinuousState(currentTimedPrjState.get_zones()[0], curStateArray, newStates, firedTran); + +// ContinuousRecordSet newAssignValues = +// updateContinuousState(currentTimedPrjState.get_zones()[0], +// curStateArray, newStates, firedTran); + + ContinuousRecordSet newAssignValues = new ContinuousRecordSet(); + + //*newStates = + //*updateContinuousState(currentTimedPrjState.get_zones()[0], + //*curStateArray, newStates, firedTran, + //*newAssignValues); + + newStates = + updateContinuousState(currentTimedPrjState.get_zones()[0], + curStateArray, newStates, firedTran, + newAssignValues); + + // Check the cached values. Current this assumes no shared continuous variables. + State nextState = this.getNextState(newStates[this.getLpn().getLpnIndex()], firedTran); + if( nextState != null){ + newStates[this.getLpn().getLpnIndex()] = nextState; + } + else{ + newStates[this.getLpn().getLpnIndex()] = + this.addState(newStates[this.getLpn().getLpnIndex()]); + this.addStateTran(curStateArray[this.getLpn().getLpnIndex()], firedTran, + newStates[this.getLpn().getLpnIndex()]); + } + + + LpnTranList enabledTransitions = new LpnTranList(); + + for(int i=0; i map = lpn.getVarIndexMap(); + + for(Event e : eventSet){ + + // Extract inequality variable. + InequalityVariable iv = e.getInequalityVariable(); + + // Get the index to change the value. + int variableIndex = map.getValue(iv.getName()); + + // Flip the value of the inequality. + int[] vector = states[this.lpn.getLpnIndex()].getVariableVector(); + vector[variableIndex] = + vector[variableIndex] == 0 ? 1 : 0; + } + + HashSet newlyEnabled = new HashSet(); + // Update the enabled transitions according to inequalities that have changed. + for(int i=0; i newlyEnabled = new HashSet(); + // Update the enabled transitions according to inequalities that have changed. + for(int i=0; i variableIndecies = lpn.getContinuousIndexMap(); + int contIndex = variableIndecies.getValue(tmpVar.getName()); + + // Package up the information into a the index. Note the current rate doesn't matter. + LPNContinuousPair index = + new LPNContinuousPair(lpn.getLpnIndex(), contIndex, 0); + +// int value = newZones[0] +// .getDbmEntryByPair(LPNTransitionPair.ZERO_TIMER_PAIR, +// index); + int value = newZones[0].getUnwarpedUpperBound(index); + + if(iv.exceedConstant(value)){ + +// inequalityList = +// newZones[0].addSetItem(inequalityList, +// new Event(iv), +// localStates[firedRate.get_lpnIndex()]); + inequalityList = + Zone.addSetItem(newZones[0], inequalityList, + new Event(iv), + localStates[firedRate.get_lpnIndex()]); + } + } + } + } + + // Fire the inequalities. +// if(inequalityList.size() >0){ +// if(inequalityList.size() >1){ +// throw new IllegalStateException("Expected a single set of " +// + "inequalities, but got something more."); +// } +// return fire(curSgArray, newTimedPrjState, inequalityList.getFirst()); +// } + + + return newTimedPrjState; + } + + /** + * This method handles the extracting of the new rate and continuous variable assignments. + * @param z + * The previous zone. + * @param currentValuesAsString + * The current values of the Boolean variables converted to strings. + * @param oldStates + * The current states. + * @param firedTran + * The fired transition. + * @return + * The continuous variable and rate assignments. + */ +// private ArrayList> +// updateContinuousState(Zone z, +// State[] oldStates, State[] newStates, Transition firedTran){ +// private ArrayList +// updateContinuousState(Zone z, +// State[] oldStates, State[] newStates, Transition firedTran){ + //*private State[] updateContinuousState(Zone z, + private State[] updateContinuousState(Equivalence z, + State[] oldStates, State[] newStates, Transition firedTran, + ContinuousRecordSet updateContinuousRecords){ + // Convert the current values of Boolean variables to strings for use in the + // Evaluator. + HashMap currentValuesAsString = + this.lpn.getAllVarsWithValuesAsString(oldStates[this.lpn.getLpnIndex()].getVariableVector()); + + + // Accumulates a set of all transitions that need their enabling conditions + // re-evaluated. + HashSet needUpdating = new HashSet(); + + + HashSet ineqNeedUpdating= + new HashSet(); + + HashSet rateIneqNeedUpdate = + new HashSet(); + + // Accumulates the new assignment information. +// ArrayList updateContinuousRecords = +// new ArrayList(); + +// ContinuousRecordSet updateContinuousRecords = +// new ContinuousRecordSet(); + + // Accumulates the new assignment information. +// ArrayList> newAssignValues +// = new ArrayList>(); + + /* + * 0. old rate is zero, new rate is zero. + * Lookup the zero rate in the _rateZeroContinuous and add any new continuous assignments. + * 1. old rate is zero, new rate is non-zero. + * Remove the rate from the _rateZeroContinuous and add the zone. + * 2. old rate is non-zero, new rate is zero. + * Add the variable with its upper and lower bounds to _rateZeroContinuous. + * 3. old rate is non-zero, new rate is non-zero. + * Get the LPNContinuousPair from the _indexToTimerPair and change the value. + * + * Note: If an assignment is made to the variable, then it should be considered as a + * new variable. + */ + + // Update rates +// final int OLD_ZERO = 0; // Case 0 in description. +// final int NEW_NON_ZERO = 1; // Case 1 in description. +// final int NEW_ZERO = 2; // Case 2 in description. +// final int OLD_NON_ZERO = 3; // Case 3 in description. +// if(Options.getTimingAnalysisFlag()){ +// newAssignValues.add(new HashMap()); +// newAssignValues.add(new HashMap()); +// newAssignValues.add(new HashMap()); +// newAssignValues.add(new HashMap()); +// } + + for(String key : this.lpn.getContVars()){ + + UpdateContinuous newRecord = new UpdateContinuous(); + + // Get the pairing. + int lpnIndex = this.lpn.getLpnIndex(); + int contVarIndex = this.lpn.getContVarIndex(key); + + // Package up the indecies. + LPNContinuousPair contVar = new LPNContinuousPair(lpnIndex, contVarIndex); + + //Integer newRate = null; + IntervalPair newRate = null; + IntervalPair newValue= null; + + //} + + // Update continuous variables. + if (this.lpn.getContAssignTree(firedTran.getLabel(), key) != null) { + + newRecord.set_newValue(true); + + // Get the new value. + newValue = this.lpn.getContAssignTree(firedTran.getLabel(), key) + .evaluateExprBound(currentValuesAsString, z, null); + + // Get each inequality that involves the continuous variable. + ArrayList inequalities = + this.lpn.getContVar(contVarIndex).getInequalities(); + + /* If inequalities is null, create a list */ + if(inequalities == null){ + inequalities = new ArrayList(); + } + + ineqNeedUpdating.addAll(inequalities); + + } + + // Check if there is a new rate assignment. + if(this.lpn.getRateAssignTree(firedTran.getLabel(), key) != null){ + newRate = this.lpn.getRateAssignTree(firedTran.getLabel(), key) + .evaluateExprBound(currentValuesAsString, z, null); + + contVar.setCurrentRate(newRate.getSmallestRate()); + + + newRecord.set_lcrPair(new LPNContAndRate(contVar, newRate)); + + } + +// if(newValue == null && newRate == null){ +// // If nothing was set, then nothing needs to be done. +// continue; +// } + + + if(newValue == null && newRate == null){ + // Need to check if the current rate will be set to non-zero + // when it is currently zero. + newRate = z.getRateBounds(contVar); + + if(newRate.isZero() || !(newRate.containsZero())){ + // Nothing needs to be done, so continue. + continue; + } + newRecord.set_lcrPair(new LPNContAndRate(contVar, newRate)); + + // Since we are going to be adding the continuous variable back + // into the zone, the value should be treated as new. + newValue = z.getContinuousBounds(contVar); + newRecord.set_Value(newValue); + newRecord.set_newValue(true); + + // Set the rate to the lower bound or zero. + contVar.setCurrentRate(z.rateResetValue(contVar)); + } + + // If the value did not get assigned, put in the old value. + if(newValue == null){ + newValue = z.getContinuousBounds(contVar); + if (newValue == null) { + newValue = new IntervalPair(0,0); + } + newRecord.set_newValue(false); + newRecord.set_Value(newValue); + } + else{ + // Put in the new value. + newRecord.set_Value(newValue); + + // Declare this record has a new value. + newRecord.set_newValue(true); + } + + + // If a new rate has not been assigned, put in the old rate. + if(newRate == null){ + newRate = z.getRateBounds(contVar); + newRecord.set_lcrPair(new LPNContAndRate(contVar, newRate)); + + // Set the rate to the lower bound or zero. + contVar.setCurrentRate(z.rateResetValue(contVar)); + } + +// newRecord.set_lcrPair(new LPNContAndRate(contVar, newRate)); +// +// // Set the rate to the lower bound or zero. +// contVar.setCurrentRate(z.getSmallestRate(contVar)); + + // Check if the new assignment gives rate zero. +// boolean newRateZero = newRate.singleValue() ? +// newRate.get_LowerBound() == 0 : false; + + boolean newRateZero = newRate.isZero(); + + // Check if the variable was already rate zero. + boolean oldRateZero = z.getCurrentRate(contVar) == 0; + + newRecord.set_oldZero(oldRateZero); + newRecord.set_newZero(newRateZero); + + updateContinuousRecords.add(newRecord); + + // Put the new value in the appropriate set. +// if(oldRateZero){ +// if(newRateZero){ +// // Old rate is zero and the new rate is zero. +// newAssignValues.get(OLD_ZERO).put(new LPNContAndRate(contVar, newRate), newValue); +// } +// else{ +// // Old rate is zero and the new rate is non-zero. +// newAssignValues.get(NEW_NON_ZERO).put(new LPNContAndRate(contVar, newRate), newValue); +// } +// } +// else{ +// if(newRateZero){ +// // Old rate is non-zero and the new rate is zero. +// newAssignValues.get(NEW_ZERO).put(new LPNContAndRate(contVar, newRate), newValue); +// } +// else{ +// // Old rate is non-zero and the new rate is non-zero. +// newAssignValues.get(OLD_NON_ZERO).put(new LPNContAndRate(contVar, newRate), newValue); +// } +// } + + // Check for inequalities that need to be changed based on a + // rate change. + + // Get each inequality that involves the continuous variable. + ArrayList rateInequalities = + this.lpn.getContVar(contVarIndex).getInequalities(); + + /* If inequalities is null, create a list */ + if(rateInequalities == null){ + rateInequalities = new ArrayList(); + } + + // Rate assignments can change the value of inequalities if + // the value of the variable is equal to the constant + // for the inequality variable. + for(InequalityVariable iv: rateInequalities){ + // Assume that the variable can have a rate change alter + // the inequality if the upper and lower bound for the + // values is within one and the constant is in between. + + boolean nearConstant = false; + + // Determine in the current value of the variable is + // within 1 unit in the warped space. + if(contVar.getCurrentRate() > 0){ + nearConstant = + Math.abs(ContinuousUtilities.chkDiv(newValue.get_UpperBound(), + contVar.getCurrentRate(), true) + - ContinuousUtilities.chkDiv(newValue.get_LowerBound(), + contVar.getCurrentRate(), false)) + <= 1.0; + } + else if (contVar.getCurrentRate()<0){ + nearConstant = + Math.abs(ContinuousUtilities.chkDiv(newValue.get_LowerBound(), + contVar.getCurrentRate(), true) + - ContinuousUtilities.chkDiv(newValue.get_UpperBound(), + contVar.getCurrentRate(), false)) + <= 1.0; + } + else{ + nearConstant=Math.abs(newValue.get_UpperBound() + - newValue.get_LowerBound()) <= 1.0; + } + + + if(nearConstant + && newValue.get_LowerBound() <= iv.getConstant() + && newValue.get_UpperBound() >= iv.getConstant()){ + + int[] currentarray = newStates[this.lpn.getLpnIndex()].getVariableVector(); + int ineqIndex = this.lpn.getVarIndexMap().get(iv.getName()); + if(contVar.getCurrentRate() >= 0){ + if(iv.isGreaterThan() && currentarray[ineqIndex] != 1){ + // If we are an inequality of the form v>=a, v>a, + // a<=v, or a=v, or a>v, then the inequality is treated as false + // when the rate is positive. So if the inequality is true + // add it to the inequalities to change. + rateIneqNeedUpdate.add(iv); + needUpdating.addAll(iv.getTransitions()); + } + } + else{ + // The rate is negative, so reverse the logic in the above. + if(iv.isGreaterThan() && currentarray[ineqIndex] != 0){ + // If we are an inequality of the form v>=a, v>a, + // a<=v, or a=v, or a>v, then the inequality is treated as true + // when the rate is negative. So if the inequality is false + // add it to the inequalities to change. + rateIneqNeedUpdate.add(iv); + needUpdating.addAll(iv.getTransitions()); + } + } + } + } + + } + + // If inequalities have changed, get a new copy of the current state. This is assuming + // only one local state will change. + if(ineqNeedUpdating.size() != 0 || rateIneqNeedUpdate.size() != 0){ + newStates[this.getLpn().getLpnIndex()] = newStates[this.getLpn().getLpnIndex()].clone(); + } + + + // Get the vector to change. + int[] newVectorArray = newStates[this.lpn.getLpnIndex()].getVariableVector(); + + // Update the inequalities. + for(InequalityVariable ineq : ineqNeedUpdating){ + int ineqIndex = this.lpn.getVarIndexMap(). + get(ineq.getName()); + + // Add the transitions that this inequality affects. + needUpdating.addAll(ineq.getTransitions()); + + + HashMap continuousValues + = new HashMap(); + + for(UpdateContinuous record : updateContinuousRecords.keySet()){ + continuousValues.put(record.get_lcrPair(), record.get_Value()); + } +// continuousValues.putAll(newAssignValues.get(OLD_ZERO)); +// continuousValues.putAll(newAssignValues.get(NEW_NON_ZERO)); +// continuousValues.putAll(newAssignValues.get(NEW_ZERO)); +// continuousValues.putAll(newAssignValues.get(OLD_NON_ZERO)); + + // Adjust state vector values for the inequality variables. +//<<<<<<< StateGraph.java +// int[] newVectorArray = newStates[this.lpn.getLpnIndex()].getVector(); +//======= +// int[] newVectorArray = oldStates[this.lpn.getLpnIndex()].getVector(); + +//>>>>>>> 1.54 + + newVectorArray[ineqIndex] = ineq.evaluate(newVectorArray, z, continuousValues); + } + + + // Update the inequalities. + for(InequalityVariable ineq : rateIneqNeedUpdate){ + int ineqIndex = this.lpn.getVarIndexMap(). + get(ineq.getName()); + + LPN lpn = ineq.get_lpn(); + + // Build the index object + LPNContinuousPair lcv = + new LPNContinuousPair(lpn.getLpnIndex(), + lpn.getContVarIndex(ineq.getContVariables().get(0).getName())); + + // Get the record value. + UpdateContinuous upc = updateContinuousRecords.get(lcv); + + // Get the current rate. + int rate = upc.get_lcrPair().get_lcPair().getCurrentRate(); + + // TODO: add logic to correctly evaluate the inequality due to rates. + + int newvalue = 0; + + if(ineq.isGreaterThan() && rate > 0){ + newvalue = 1; + } + else if(ineq.isGreaterThan() && rate < 0){ + newvalue = 0; + } + else if(ineq.isLessThan() && rate > 0){ + newvalue = 0; + } + else if(ineq.isLessThan() && rate < 0){ + newvalue = 1; + } + + // Flip the value of the inequality variable. +// newVectorArray[ineqIndex] = newVectorArray[ineqIndex] == 0 ? 1 : 0; + newVectorArray[ineqIndex] = newvalue; + } + + + // Do the re-evaluating of the transitions. + for(Transition t : needUpdating){ + // Get the index of the LPN and the index of the transition. + int lpnIndex = t.getLpn().getLpnIndex(); + int tranIndex = t.getIndex(); + + // Get the enabled vector from the appropriate state. + int[] vector = newStates[lpnIndex].getVariableVector(); + int[] marking = newStates[lpnIndex].getMarking(); + boolean[] previouslyEnabled = newStates[lpnIndex].getTranVector(); + + // Set the (possibly) new value. + + boolean needToUpdate = true; + String tranName = t.getLabel(); + if (this.lpn.getEnablingTree(tranName) != null + && this.lpn.getEnablingTree(tranName) + .evaluateExpr(this.lpn.getAllVarsWithValuesAsString(vector)) == 0.0) { + if (previouslyEnabled[tranIndex] && !t.isPersistent()) + previouslyEnabled[tranIndex] = false; + continue; + } + + if (this.lpn.getPreset(tranName) != null && this.lpn.getPreset(tranName).length != 0) { + for (int place : this.lpn.getPresetIndex(tranName)) { + if (marking[place]==0) { + needToUpdate = false; + break; + } + } + } + if (needToUpdate) { + // if a transition is enabled and it is not recorded in the enabled transition vector + previouslyEnabled[tranIndex] = true; + } + + } + +// return newAssignValues; +// return updateContinuousRecords; + + return newStates; + } + + @Override + public String toString() { + return "StateGraph [lpn=" + lpn + "]"; + } + + /** + * Find all locally enabled transitions in the initial local state, and construct the corresponding tranVector in this state. + * @param initialVector + * @return + */ + public boolean[] genInitTranVector(int[] initialVector) { + boolean[] initEnabledTrans = new boolean[this.lpn.getAllTransitions().length]; + for (int i=0; i< this.lpn.getAllTransitions().length; i++) { + Transition transition = this.lpn.getAllTransitions()[i]; + Place[] tranPreset = this.lpn.getTransition(transition.getLabel()).getPreset(); + String tranName = transition.getLabel(); + boolean presetNotMarked = false; + if (this.lpn.getPreset(tranName) != null && this.lpn.getPreset(tranName).length != 0) { + for (int j=0; j S" + nextState.getIndex() + "(" + nextState.getLpn().getLabel() + ")"); + } + } + System.out.println("--------------End Of Next State Map----------------------"); + + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/StateTran.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/StateTran.java new file mode 100644 index 000000000..fc75fabac --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/StateTran.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package edu.utah.ece.async.lema.verification.platu.stategraph; + +import edu.utah.ece.async.lema.verification.platu.platuLpn.LPNTran; + +/** + * + * @author ldtwo + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class StateTran { + + public State head; + public State tail; + public LPNTran lpnTran; + int hashVal = 0; + + public StateTran(State tail, LPNTran lpnTran, State head) { + this.head = head; + this.tail = tail; + this.lpnTran = lpnTran; + } + + @Override + public int hashCode() { + if(hashVal == 0){ + final int prime = 31; + hashVal = 17; + hashVal = prime * hashVal + head.hashCode(); + hashVal = prime * hashVal + lpnTran.hashCode(); + hashVal = prime * hashVal + tail.hashCode(); + } + + return hashVal; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + + if (obj == null) + return false; + + if (getClass() != obj.getClass()) + return false; + + StateTran other = (StateTran) obj; + if (head == null) { + if (other.head != null) + return false; + } + else if (!head.equals(other.head)){ + return false; + } + + if (lpnTran == null) { + if (other.lpnTran != null) + return false; + } + else if (!lpnTran.equals(other.lpnTran)){ + return false; + } + + if (tail == null) { + if (other.tail != null) + return false; + } + else if (!tail.equals(other.tail)){ + return false; + } + + return true; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/UpdateTimer.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/UpdateTimer.java new file mode 100644 index 000000000..fe9387eb8 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/platu/stategraph/UpdateTimer.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package edu.utah.ece.async.lema.verification.platu.stategraph; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.text.DecimalFormat; +import javax.swing.Timer; + +/** + * + * @author ldmtwo + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public abstract class UpdateTimer { + + public static int UPDATE_DURATION = 1000;//millisec + DecimalFormat df1 = new DecimalFormat("00.000"); + DecimalFormat df2 = new DecimalFormat("###,###,###,##0"); + long initialMemory = 0; + Timer timer; + + public abstract int getNumStates(); + + public abstract int getStackHeight(); + + public abstract String getLabel(); + + public UpdateTimer(int delay) { + UPDATE_DURATION = delay; + initialMemory = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + timer = new Timer(delay, al); + // timer.start(); + } + + public void start() { + timer.start(); + } + + public void stop() { + timer.stop(); + } + + public void print() { + al.actionPerformed(null); + } + final ActionListener al = new ActionListener() { + + long lastTime = System.currentTimeMillis(); + final long startTime = lastTime; + int lastStates = 0; + + @Override + public void actionPerformed(ActionEvent e) { + try { + System.gc(); + int numStates = getNumStates(); + long now = System.currentTimeMillis(); + long totalMem, freeMem; + totalMem = Runtime.getRuntime().totalMemory(); + freeMem = Runtime.getRuntime().freeMemory(); + long mem = (totalMem - freeMem - initialMemory) / 1024; + int deltaStates = numStates - lastStates; + long timeMS = now - startTime; + double deltaTime = (UPDATE_DURATION / 1000f); + long timeSec = (long) (timeMS / 1000f); + long h = timeSec / 3600, m = (timeSec % 3600) / 60; + double s = (timeMS / 1000f) - h * 3600 - m * 60; + int statesPerSec = (int) (deltaStates / deltaTime); + String timeStr = String.format("%d:%02d:%2s", h, m, df1.format(s)); + int bytesPerState = (int) (1024l * mem / numStates); + System.out.printf("Free:%-10s Used: %-10s Total: %-10s Stack: %-7s %s states/sec %s B/state %s\n", + df2.format(freeMem / 1024 / 1024) + " mb", + df2.format(mem / 1024) + " mb", + df2.format(totalMem / 1024 / 1024) + " mb (" + + df2.format(totalMem / bytesPerState / 1000) + " K states max)", + df2.format(getStackHeight()) + "", + String.format("%5s %5s ", getLabel(), + "|S| =" + df2.format(numStates)) + " " + df2.format(statesPerSec), + df2.format(bytesPerState), + timeStr); + lastTime = System.currentTimeMillis(); + lastStates = numStates; + } catch (Exception ex) { +// ex.printStackTrace(); + } + } + }; +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/Interval.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/Interval.java new file mode 100644 index 000000000..ba9885eae --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/Interval.java @@ -0,0 +1,187 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.archive; + + +/** + * Represents an interval of real numbers [min,max]. + * + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Interval { + + /* + * Abstraction: represents the set of numbers [min,max]. + */ + + + /* + * Representation Invariant: The behavior is undefined for + * min > max. + */ + + private int _min,_max; + + /** + * Creates a degenerate interval representing {0}. + */ + public Interval(){ + this._min = this._max = 0; + } + + /** + * Creates a degenerate interval representing {value}. + * @param value + */ + public Interval(int value){ + this._min = this._max = value; + } + + /** + * Creates an interval the interval [min,max]. + * @param min The minimum value. + * @param max The maximum value. + */ + public Interval(int min, int max){ + this._min = min; + this._max = max; + } + + /** + * Creates a new instance of Interval. + * + * @return Creates an Interval [a,b] where + * a is the min value of this instance and b + * is the max value of this instance. + */ + @Override + protected Interval clone() { + + return new Interval(this._min, this._max); + } + + /** + * Determines if the obj is equal to this Interval. + * + * @return True if obj is an Interval instance + * that satisfies obj.min = this.min and + * obj.max = obj.max. + */ + @Override + public boolean equals(Object obj) { + + if(!(obj instanceof Interval)){ + return false; + } + + Interval that = (Interval) obj; + + return this.equals(that); + } + + /** + * Determines if two Intervals are equal. + * @param that The interval to compare this + * Interval to. + * @return True if and only if + * that.min == this.min and that.max == this.max. + */ + public boolean equals(Interval that){ + return that._min == this._min && that._max == this._max; + } + + /** + * @return Returns a hashcode. + */ + @Override + public int hashCode() { + + return 31*this._min + this._max; + } + + /** + * @return Returns a string representation of this Interval. + */ + @Override + public String toString() { + + if( this._min > this._max){ + return "{}"; + } + + if( this._min == this._max){ + return "{" + this._min + "}"; + } + + return "[" + this._min + "," + this._max + "]"; + } + + /** + * Determines if the Interval has at least one value. + * @return True if and only this this.min <= this.max. + */ + public boolean nonDegenerate(){ + return this._min <= this._max; + } + + /** + * Determines if the Interval represents a single value. + * @return True if and only if this.min == this.max. + */ + public boolean signalValue(){ + return this._min == this._max; + } + + /** + * @return Returns the minimum value. Assumes non-empty. + */ + public int get_Min(){ + return this._min; + } + + /** + * Sets the minimum value. + * @param min + */ + public void set_Min(int min){ + this._min = min; + } + + /** + * + * @return Returns the maximum value. Assumes non-empty. + */ + public int get_Max(){ + return this._max; + } + + /** + * Sets the maximum value. + * @param max + */ + public void set_Max(int max){ + this._max = max; + } + + /** + * Determines if the Interval is just the zero value. + * @return True if the Interval is {0}. + */ + public boolean isZero(){ + return signalValue() && this._min == 0; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/OctMember.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/OctMember.java new file mode 100644 index 000000000..3b7492427 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/OctMember.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.archive; + +import edu.utah.ece.async.lema.verification.lpn.LPN; + +/** + * Base class for the member variables of the octagons. + * + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public abstract class OctMember { + + /* + * Abstraction Function: Gathers together common elements of the octagon + * variables timer and continuous variables. + */ + + /* + * The associated LPN for this variable. + */ + protected LPN _lpn; + + /* + * The variable number taking into account all variables for the + * LPN. + */ + protected int _absReference; + + /* + * An interval reference. Timers can use this for caching the delay. + * Rate zero continuous variable can use this for caching the current + * range of values. Non-rate zero variables can use this for caching + * range of rates. + */ + protected Interval _range; + + + /** + * Get the associated LPN. + * @return The associated LPN. + */ + public LPN get_Lpn() { + return _lpn; + } + + /** + * Set the associated LPN. + * @param _lpn + */ + public void set_Lpn(LPN _lpn) { + this._lpn = _lpn; + } + + /** + * Gets the number of the variable. + * @return The number of the variable. + */ + public int get_absReference() { + return _absReference; + } + + /** + * Sets the number of the variable. + * @param _absReference The number of the variable. + */ + public void set_absReference(int _absReference) { + this._absReference = _absReference; + } + + /** + * Gets the range. + * @return The range. + */ + public Interval get_range() { + return _range; + } + + /** + * Sets the range. + * @param _range The range. + */ + public void set_range(Interval _range) { + this._range = _range; + } + + + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/PreContinuous.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/PreContinuous.java new file mode 100644 index 000000000..493ca0dc2 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/PreContinuous.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.archive; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public abstract class PreContinuous extends OctMember { + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/RateNonZero.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/RateNonZero.java new file mode 100644 index 000000000..72a5800c0 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/RateNonZero.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.archive; + + +/** + * Continuous variables whose current rate is not zero. + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class RateNonZero extends PreContinuous { + + /* + * Abstraction Function: This class represents a continuous + * variable that has a non-zero current rate. In this representation, + * super._range stores the cached range of rates. + */ + + /* + * Representation Invariant: + * super._range -> current range of rates. + * + */ + + /** + * + * @return + */ + public Interval getRangeOfRates(){ + return super.get_range(); + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/RateZero.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/RateZero.java new file mode 100644 index 000000000..0d0df6264 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/RateZero.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.archive; + + +/** + * Continuous variable whose current rate is zero. + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class RateZero extends PreContinuous { + + + public Interval getValues(){ + return super.get_range(); + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/Timer.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/Timer.java new file mode 100644 index 000000000..8fe78296d --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/archive/Timer.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.archive; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Timer extends OctMember { + + /* + * Abstraction Function: Represents a timer associated with a clock. + * In this representation, super._range caches the delay. + */ + + /* + * Representation Invariant: + * super._range -> delay. + */ + + /** + * Get the cached delay. + * @return The current delay. + */ + public Interval getDelay(){ + return super.get_range(); + } + + /** + * Sets the current delay. + * @param delay The current delay. + */ + public void setDelay(Interval delay){ + super.set_range(delay); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/DBMLL.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/DBMLL.java new file mode 100644 index 000000000..96bb6dd23 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/DBMLL.java @@ -0,0 +1,708 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.dbm2; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +/** + * This class is for storing and manipulating timing zones via difference bound matrices. + * The underlying structure is backed by linked lists which yields the name + * DBMLL (difference bound matrix linked list). A difference bound matrix has the form + * t0 t1 t2 t3 + * t0 m00 m01 m02 m03 + * t1 m10 m11 m12 m13 + * t2 m20 m21 m22 m23 + * t3 m30 m31 m32 m33 + * where tj - ti<= mij. In particular, m0k is an upper bound for tk and -mk is a lower + * bound for tk. + * + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class DBMLL { + + // Abstraction Function : + // The difference bound matrix is represented by ArrayList> matrix. + // To match the philosophy of a two dimensional array being stored as rows, + // each ArrayList represents a row of the matrix. + // For example: + // 1 2 3 this row is a ArrayList stored at index zero + // 4 5 6 this row is a ArrayList stored at index one + // 7 8 9 this row is a ArrayList stored at index two. + // In order to keep track of the upper and lower bounds of timers from when they are first + // enabled, the matrix will be augmented by a row and a column. The first row will contain + // the upper bounds and the first column will contain the negative of the lower bounds. + // For one timer t1 that is between 2 and 3, we might have + // lb t0 t1 + // ub x 0 3 + // t0 0 m m + // t1 -2 m m + // where x is not important (and will be given a zero value), 3 is the upper bound on t1 + // and -2 is the negative of the lower bound. The m values represent the actual difference + // bound matrix. Also note that the column heading are not part of the stored representation + // lb stands for lower bound while ub stands for upper bound. + // This upper and lower bound information is called the Delay for a Transition object. + // Since a timer is tied directly to a Transition, the timers are index by the corresponding + // Transition's index in a LPNTranslator. + + // Representation invariant : + // Integer.MAX_VALUE is used to logically represent infinity. + // The lb and ub values for a timer should be set when the timer is enabled. + + private ArrayList> matrix; // The underlying matrix. + + private HashMap enabledTimers; // Maps timer to their index. + private HashMap getTimer; // Maps the index to the timer. + + public static final int INFINITY = Integer.MAX_VALUE; + + + public DBMLL() + { + matrix = new ArrayList>(); + enabledTimers = new HashMap(); + getTimer = new HashMap(); + + } + + /** + * Creates a difference bound matrix based off the initial markings. + * @param trans The associated LPN. + */ + public DBMLL(LPNTranslator lpn) + { +// int counter = 0; // Counter for keeping track of the number of transitions +// // being included in the zone. + + enabledTimers = new HashMap(); + getTimer = new HashMap(); + + // Get the enabled transitions. + HashSet transitions = lpn.getEnabledTransitions(lpn.getInitialMarkings()); + + initializeZone(lpn, transitions); + + advanceTime(); + + recanonicalize(); + +// matrix = new ArrayList>(); // Set up the matrix. +// +// ArrayList zeroRow = new ArrayList(); // Create the zeroth row. +// zeroRow.add(0); // This will end up being the (0,0) position of the matrix. +// // which is the 'x' in the second diagram of the +// // of the Abstraction Function. It will be given zero value. +// +// // Initialize the zero row to have the upper bounds of each timer. +// for(Integer i : transitions) +// { +// enabledTimers.put(i, counter); // Add an entry tying the timer to +// // its index in the DBM part of matrix. +// +// getTimer.put(counter, i); // Add the reverse look up. +// +// counter++; +// +// zeroRow.add(lpn.getDelayLowerBound(i)); // Initialize the upper bound. +// } +// +// // Add the zero row to the matrix. +// matrix.add(zeroRow); +// +// // Create the other rows of the matrix. +// for(int i=0; i row = new ArrayList(); +// +// // Set up the lower bound for the ith timer. +// row.add(lpn.getDelayLowerBound(getTimer.get(i))); +// +// // Fill up the array with zeros. +// for(int j=0; j timers) + { + // check logic for zero timer. + + int counter =2; + matrix = new ArrayList>(); // Set up the matrix. + + ArrayList zeroRow = new ArrayList(); // Create the zeroth row. + zeroRow.add(0); // This will end up being the (0,0) position of the matrix. + // which is the 'x' in the second diagram of the + // of the Abstraction Function. It will be given zero value. + zeroRow.add(0); // upper bound for the t0 timer. + + // Initialize the zero row to have the upper bounds of each timer. + for(Integer i : timers) + { + enabledTimers.put(i, counter); // Add an entry tying the timer to + // its index in the DBM part of matrix. + + getTimer.put(counter, i); // Add the reverse look up. + + counter++; + + // Initialize the upper bound. + zeroRow.add(lpn.getDelayUpperBound(i, lpn.getInitialBooleanValues())); + } + + // Add the zero row to the matrix. + matrix.add(zeroRow); + + // Create the t0 row. + ArrayList t0Row = new ArrayList(); + for(int i=0; i row = new ArrayList(); + + // Set up the lower bound for the ith timer. + row.add(lpn.getDelayLowerBound(getTimer.get(i), lpn.getInitialBooleanValues())); + + // Fill up the array with zeros. + for(int j=0; j>(); + + int[][] zone = state.getZone(); + + for(int i=0; i row = new ArrayList(); + + for(int j=0; j(); + getTimer = new HashMap(); + for(int i=0; i thisTimers = enabledTimers.keySet(); +// Set otherTimers = otherZone.enabledTimers.keySet(); +// +// if(thisTimers.size() != otherTimers.size()) +// { +// return false; +// } +// +// for(Integer i : thisTimers) +// { +// if(!otherTimers.contains(i)) +// { +// return false; +// } +// } +// +// for(int i=0; i timers = enabledTimers.keySet(); +// +// int counter =0; +// for(Integer i : timers) +// { +// result[counter++] = i; +// } + + + int counter =0; + for(int i=2; i enabledTransitions) + { + + + // Restrict to lower bound. + restrictToLowerBound(transition); + + // Tighten loose bounds. + recanonicalize(); + + // Project out timer. + project(transition); + + // Delete any timer that has lost its token. + ArrayList integersToDelete = new ArrayList(); + + for(Integer i : enabledTimers.keySet()) + { + if(!enabledTransitions.contains(i)) + { + integersToDelete.add(i); + } + } + + for(Integer i : integersToDelete) + { + project(i); + } + + + //int currentSize = enabledTimers.size(); + + HashSet newTransitions = new HashSet(); + for(Integer i : enabledTransitions) + { + if(!enabledTimers.keySet().contains(i)) + { + newTransitions.add(i); + } + } + + + for(Integer i : newTransitions) + { + //enabledTimers.put(i, currentSize); + //getTimer.put(currentSize, i); + + enabledTimers.put(i, matrix.size()); + getTimer.put(matrix.size(), i); + + matrix.get(0).add(lpn.getDelayUpperBound(i, newBooleanValues)); + matrix.get(1).add(0); // initialize zero element to zero. + for(int j=2; j< matrix.size(); j++) + { + if(!getTimer.containsKey(j)) // If this timer has been deleted, continue. + { + matrix.get(j).add(0); + continue; + } + + if(newTransitions.contains(getTimer.get(j))) // If the transition is new + { + matrix.get(j).add(0); // j+1 since timers start at 1 but are zero + // based indexed. + } + else + { + matrix.get(j).add(getEntry(j, 1)); + } + } + + ArrayList row = new ArrayList(); + + row.add(lpn.getDelayLowerBound(i, newBooleanValues)); + row.add(0); // Initialize zero element to zero. + for(int j=2; j getEntry(i,k) + getEntry(k,j)) + { + setEntry(i,j, getEntry(i,k) + getEntry(k,j)); + if(i==j && getEntry(i,j) != 0) + { + throw new NegativeDiagonalException("A diagonal entry was set" + + "to a negative value"); + } + } + } + } + } + } + + public boolean hasMetDelay(int timer) + { + return enabledTimers.keySet().contains(timer) ? + getEntry(1, enabledTimers.get(timer))>-1*getLowerBound(timer) : false; + } + + public HashSet hasMetDelay() + { + HashSet timers = new HashSet(); + + for(Integer i : enabledTimers.keySet()) + { + if(hasMetDelay(i)) + { + timers.add(i); + } + } + + return timers; + } + + public int getLowerBound(int timer) + { + return matrix.get(enabledTimers.get(timer)).get(0); + } + + private void restrictToLowerBound(int timer) + { + matrix.get(enabledTimers.get(timer)).set(1, getLowerBound(timer)); + } + +// private void advanceToUpperBound(int timer) +// { +// matrix.get(1).set(enabledTimers.get(timer), getUpperBound(timer)); +// } + + public int getUpperBound(int timer) + { + // fix. + return matrix.get(0).get(enabledTimers.get(timer)); + } + +// public int getMatrixValue(int timer1, int timer2) +// { +// return getEntry(enabledTimers.get(timer1), enabledTimers.get(timer2)); +// } + +// private void set(int i, int j) +// { +// +// } + + @SuppressWarnings("unused") + private int get(int i, int j) + { + return matrix.get(i+1).get(j+1); + } + + /** + * Indexed by timers. + * @param i + * @param j + * @param value + */ + @SuppressWarnings("unused") + private void set(int i, int j, int value) + { + matrix.get(i+1).set(j+1, value); + } + + private void setEntry(int i, int j, int value) + { + matrix.get(i).set(j, value); + } + + + @Override + public DBMLL clone() + { + DBMLL newZone = new DBMLL(); + + //newZone.matrix = (ArrayList>) this.matrix.clone(); + //newZone.enabledTimers = (HashMap) this.enabledTimers; + //newZone.getTimer = (HashMap) this.getTimer; + + newZone.matrix = new ArrayList>(); + for(int i=0; i row = new ArrayList(); + for(int j=0; j(this.enabledTimers); + newZone.getTimer = new HashMap(this.getTimer); + + return newZone; + } + + + public boolean mustFire(int transition) + { + int lowerBound = matrix.get(enabledTimers.get(transition)).get(1); + int upperBound = matrix.get(0).get(enabledTimers.get(transition)); + + return -1 * lowerBound >= upperBound; + } + + + public class NegativeDiagonalException extends RuntimeException + { + /** + * The default serialVersionUID. + */ + private static final long serialVersionUID = 1L; + + public NegativeDiagonalException(String message) + { + super(message); // Use the default constructor. + } + } + + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/IDBM.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/IDBM.java new file mode 100644 index 000000000..a113b65f1 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/IDBM.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.dbm2; + +/** + * This interface gives the method that are needed for the StateExploration pertaining + * to the difference bound matrices. + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public interface IDBM { + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/LPNState.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/LPNState.java new file mode 100644 index 000000000..652f038c0 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/LPNState.java @@ -0,0 +1,555 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.dbm2; + +import java.util.*; + +/** + * This class represents the state of an LhpnFile object with only places, + * boolean values, and timers on the transitions. It does not contain any + * associations such as presets and postsets of transitions and place. To obtain, + * such information, the LhpnFile will need to queried. + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class LPNState { + + // Abstraction Function: + // The state of an LHPN consists of the set of markings, the current value of + // the Boolean values, and zone to represent the state of the clocks. + // The places are labeled 0 through n and the Boolean variables are + // labeled 0 through n. Thus the state will refer to the ith place or + // jth Boolean variable. The state is given a id of -1 to represent the state has + // not been given an id yet. The member variable numberOfStates keeps track of the + // current number of states that have been given an id. + + + // Representation invariant: + // The cachedHashCode value should be initialized to a negative value. + // The id should be negative if the id has not been assigned. + // numberOfStates should represent the number of states that have been given an + // id. + // The zone array should always be square and not contain null entries. + // The enabledTimers array should not be null. + + private static long numberOfStates = 0; // Keeps track of the number of states created. + // for a state to be included, the createId + // method must be called. + + private long id; // This state's id. If it has been created. + + private boolean[] markedPlaces; // Indicates which places are marked. + + private boolean[] booleanValues; // Indicates the values of each of the booleans + + private HashSet previousStates; // The states that immediately precede this state. + + private HashSet nextStates; // The states that immediately follow this state. + + private int cachedHashCode; // Stores the hash code. + + private int[][] zone; // Keeps track of the zone information. + + private int[] enabledTimers; // Keeps track of which clocks the zone represents. + + /** + * Creates a state with the places marked and the given Boolean values. + * @param places An array that is true if the place is marked and false otherwise. + * @param values An array that is true if the Boolean variable is true and false otherwise. + */ + public LPNState(boolean[] places, boolean[] values) + { + this(places, values, new int[0], new int[0][0]); +// cachedHashCode = -1; // Initialized to a negative value to indicate no +// // hash code value calculated yet. +// markedPlaces = places.clone(); +// booleanValues = values.clone(); +// previousStates = new HashSet(); +// nextStates = new HashSet(); +// id = -1; +// zone = new int[0][0]; // Zone not being used, initialize to empty. + + + } + + public LPNState(boolean[] places, boolean[] values, int[] timers, int[][] zone) + { + cachedHashCode = -1; // Initialized to a negative value to indicate no + // hash code value calculated yet. + markedPlaces = places.clone(); + booleanValues = values.clone(); + previousStates = new HashSet(); + nextStates = new HashSet(); + id = -1; + this.zone = zone.clone(); + enabledTimers = timers.clone(); + } + + + + /** + * Create an LPNState object that represents the initial state of the LhpnFile. + * @param lpn + */ + public LPNState(LPNTranslator lpn) + { + cachedHashCode = -1; // Initialized to a negative value to indicate + // no hash code value calculated yet. + markedPlaces = lpn.getInitialMarkings(); + booleanValues = lpn.getInitialBooleanValues(); + previousStates = new HashSet(); + nextStates = new HashSet(); + id = -1; + DBMLL zoneInfo = new DBMLL(lpn); + zone = zoneInfo.getZone(); + enabledTimers = zoneInfo.getTimers(); + } + + /** + * Overrides the clone method from the object class. + */ + @Override + public LPNState clone() + { + LPNState newState = new LPNState(markedPlaces, booleanValues); + newState.cachedHashCode = this.cachedHashCode; + for(LPNState s : previousStates) + { + newState.previousStates.add(s); + } + for(LPNState s : nextStates) + { + newState.nextStates.add(s); + } + //newState.previousStates.addAll(previousStates); + //newState.nextStates.addAll(nextStates); + newState.id = this.id; + + newState.zone = this.zone.clone(); + + return newState; + } + + /** + * Initializes the LhpnFile to the state given by this LPNState. + * @return + */ + public void initializeLhpnFile() + { + } + + /** + * Tests for equality. + * @return True if o is equal to this object, false otherwise. + */ + @Override + public boolean equals(Object o) + { + // Check if the reference is null. + if(o == null) + { + return false; + } + + // Check that the type is correct. + if(!(o instanceof LPNState)) + { + return false; + } + + // Check for equality using the LPNState equality. + return equals((LPNState) o); + } + + + /** + * Tests for equality. + * @param state The state to test for equality. + * @return True if the two state are equal, false otherwise. Equality is determined by + * equality is determined based on the same marked places, the boolean values + * and the zone. + */ + public boolean equals(LPNState state) + { + // Check if the reference is null first. + if(state == null) + { + return false; + } + + // Check for reference equality. + if(this == state) + { + return true; + } + + // If the hash codes are different, then the objects are not equal. + if(this.hashCode() != state.hashCode()) + { + return false; + } + + if(markedPlaces.length != state.markedPlaces.length || + booleanValues.length != state.booleanValues.length) + { + return false; + } + + //return markedPlaces.equals(state.markedPlaces) + //&& booleanValues.equals(state.booleanValues); + for(int i=0; i timeMap = new HashMap(); + + timeMap.put(0, 0); + timeMap.put(1, 1); + + // Find the corresponding timer. + for(int i=0; i= 0) + { + timeMap.put(i+2, index+2); + } + else + { + return false; + } + } + + for(int i=2; i hashPlace = new ArrayList(); + ArrayList hashValues = new ArrayList(); + for(int i=0; i= 0) + { + result = "State " + id + " \n"; + } + else + { + result = "State 'no id' : \n"; + } + + // Prints the place markings. + result += "\tPlaces : \n\t\t" + getStringArray(markedPlaces) + "\n"; + + // Prints the Boolean values. + result += "\tBoolean Variables : \n\t\t" + getStringArray(booleanValues) + "\n"; + + // Print the previous states. + result += "\tPrevious States : \n\t\t" + getStateString(previousStates) + "\n"; + + // Print the next states. + result += "\tNext States : \n\t\t" + getStateString(nextStates) + "\n"; + + result += "\tTimers: " + getStringArray(enabledTimers) + "\n"; + + // TODO add zone info. + result += "\tZone: \n"; + for(int i=0; i getPreviousStates() + { + return (HashSet) previousStates.clone(); + } + + /** + * Returns a HashSet of the states directly following this state. + * @return Returns a HashSet of the states directly following this state. + */ + public HashSet getNextStates() + { + return (HashSet) nextStates.clone(); + } + + /** + * Creates an id number for this state. The id numbers are given sequentially. + */ + public void createId() + { + id = numberOfStates; + numberOfStates++; + } + + /** + * Gives the id of this state. To create an id for this instance, call the + * createId method. + * @return The id of this state or a negative value if no id has been created. + */ + public long getId() + { + return id; + } + + /** + * Returns the number of states given an id. + * @return The total number of states given an id. + */ + public static long getNumberOfStates() + { + return numberOfStates; + } + + /** + * Creates a string representation of an array. + * @param array The array to get the string for. + * @return A string representation of the array. + */ + public static String getStringArray(boolean[] array) + { + String result = "["; + + if(array.length > 0) + { + result += array[0]; + } + + for(int i=1; i 0) + { + if(array[0] == Integer.MAX_VALUE) + { + result += "inf"; + } + else + { + result += array[0]; + } + } + + for(int i=1; i states) + { + String result = ""; + for (LPNState s : states) + { + result += "State " + s.getId() + " "; + } + + return result; + } + + /** + * Allows access to the elements of the zone. + * @param i The row of the desired zone element. + * @param j The column of the desired zone element. + * @return The value of the zone at the i,j location. + */ + public int getZoneValue(int i, int j) + { + return zone[i][j]; + } + + public int[][] getZone() + { + return zone; + } + + public int[] getTimers() + { + return enabledTimers; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/LPNTransitionState.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/LPNTransitionState.java new file mode 100644 index 000000000..3c11a5512 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/LPNTransitionState.java @@ -0,0 +1,313 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.dbm2; + +import java.util.*; + +/** + * LPNTransitionStates adds the ability to store unprocessed enabled transitions. + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class LPNTransitionState{ + + //boolean[] enabledTransitions; // The ith position is true, then the ith transition + // is enabled. + + private LPNState state; // The underlying state. + + private HashSet enabledTransitions; // A subset of the enabled + // transitions. + + private DBMLL zone; // A mutable zone. + + /** + * Create an LPNTransition state that has an underlying states whose + * with the given marked places and boolean values. + * @param places The marked places. + * @param values The truth values of the boolean variables. + */ + public LPNTransitionState(boolean[] places, boolean[] values) + { + state = new LPNState(places, values); + enabledTransitions = new HashSet(); + } + + /** + * Create an LPNTransition state that has an underlying states + * with the given marked places and boolean values. Also starts with + * the given enabled transitions. + * @param places The marked places. + * @param values The truth values of the boolean variables. + * @param transitions The enabled transitions. + */ + public LPNTransitionState(boolean[] places, boolean[] values, HashSet transitions) { + state = new LPNState(places, values); + + enabledTransitions = new HashSet(transitions); + } + + /** + * Create an LPNTransitionState that has the baseState as the underlying state. + * @param baseState The underlying state. Note: the current enabled + * transitions are not set by this constructor. + */ + public LPNTransitionState(LPNState baseState) + { + this.state = baseState; + enabledTransitions = new HashSet(); + zone = new DBMLL(baseState); + } + + public LPNTransitionState(LPNState baseState, HashSet enabledTransitions) + { + this.state = baseState; + this.enabledTransitions = (HashSet)enabledTransitions.clone(); + zone = new DBMLL(baseState); + } + +// public LPNTransitionState(LPNTranslator trans, LPNState baseState) +// { +// this.state = baseState; +// zone = new DBMLL(baseState); +// enabledTransitions = new HashSet(); +// } + + /** + * Create an LPNTransitionState that has the initial markings, boolean values + * from the LPN associated with the LPNTranslator. Note: the current enabled + * transitions are not set by this constructor. + * @param lpn Translates between the LPN and an indexed representation. + */ + public LPNTransitionState(LPNTranslator lpn) + { + state = new LPNState(lpn); + zone = new DBMLL(state); + enabledTransitions = new HashSet(); + } + + /** + * Remove a transition from the enabled list. + * @param i The transition to remove. + */ + public void removeTransition(int i) + { + enabledTransitions.remove(i); + } + + /** + * Determines whether there are any more transitions that are enabled. + * @return True if there are more transitions that are enabled, false + * otherwise. + */ + public boolean remainingTransitions() + { + return !enabledTransitions.isEmpty(); + } + + /** + * Selects one of the remaining enabled transitions. The selected transition + * is then removed from the list of remaining transitions. + * @return One of the remaining enabled transitions. + */ + public int getATransition() { + + HashSet mustFireTransition = new HashSet(); + + // Determine if any transition must fire. + for(Integer i : enabledTransitions) + { + if(zone.mustFire(i)) + { +// enabledTransitions.remove(i); +// return i; + mustFireTransition.add(i); + } + } + + if(mustFireTransition.size() != 0) + { + enabledTransitions = mustFireTransition; + } + + Iterator nextElement = enabledTransitions.iterator(); + int transition = nextElement.next(); + enabledTransitions.remove(transition); + + return transition; + } + + /** + * Returns a new instance identical to this instance. + * @return The new instance. + */ + @Override + public LPNTransitionState clone() + { + LPNTransitionState newState = new LPNTransitionState(state); + newState.enabledTransitions.addAll(this.enabledTransitions); + + return newState; + } + + + /** + * Returns an LPNstate reflecting the change due to the given transition firing. + * @param transition The transition to fire. The base state does not change. + * @param LPNTrans An LPNTranslator that translates between the LPNState representation + * and the LPNFile object representation. + * @return The state without the transition set. + * @throws IllegalTransitionFireException If the is is illegal for the transition to fire. + */ + public LPNState getUpdatedState(int transition, LPNTranslator LPNTrans, + HashSet newTransitions) + { + if(!LPNTrans.isEnabled(transition, state.getMarkedPlaces())) + { + throw new IllegalTransitionFireException("Transition " + transition + + " has fired illegally."); + } + + // Get the Boolean values that result from firing the transition. + boolean[] newBooleanValues = LPNTrans.getNewBooleanValues(transition, + state.getBooleanValues()); + + // Get the marked places that results from firing the transition. + boolean[] newMarkedPlaces = LPNTrans.getNewMarking(transition, state.getMarkedPlaces()); + + //DBMLL newZone = zone.updateZone(transition, LPNTrans, newMarkedPlaces); + + //return new LPNState(newMarkedPlaces, newBooleanValues, + // newZone.getTimers(), newZone.getZone()); + + // TODO Pass the newTransitions as parameter to the initializeEnabledTransitions. + initializeEnabledTransitions(LPNTrans, newTransitions, newMarkedPlaces, newBooleanValues); + + + + DBMLL newZone = zone.clone(); + + newZone.updateZone(transition, LPNTrans, newBooleanValues, + newTransitions); + + // Set the enabled transitions. + //enabledTransitions = newTransitions; + + return new LPNState(newMarkedPlaces, newBooleanValues, + newZone.getTimers(), newZone.getZone()); + + } + + /** + * Returns the underlying LPNState. + * @return The underlying LPNState. + */ + public LPNState getState() + { + return state; + } + + /** + * Sets the list of enabled transitions to all the currently enabled + * transitions. + * @param transLPN A translator built on the associated LPN. + */ + public void initializeEnabledTransitions(LPNTranslator transLPN) + { + //enabledTransitions = transLPN.getEnabledTransitions(state.getMarkedPlaces()); + enabledTransitions = transLPN.getEnabledTransitions(this); + } + + public static void initializeEnabledTransitions(LPNTranslator transLPN, + HashSet enabledTransitions, boolean[] newMarkedPlaces, + boolean[] newBooleanValues) + { + + LPNTransitionState state = new LPNTransitionState( new LPNState(newMarkedPlaces, newBooleanValues)); + + // Get transitions that are enabled by markings. + transLPN.getEnabledTransitions(state, enabledTransitions); + //TODO remove transitions that are not enabled by reaching their lower bound. + +// for(Integer i : zone.hasMetDelay()) +// { +// enabledTransitions.remove(i); +// } + } + + + /** + * Checks if a transition is enabled. + * @param transition The transition to check. + * @return True if the transition is enabled, false otherwise. + */ + //public boolean checkTransitionEnabled(int transition) + //{ + // return false; + //} + + /** + * Defines an exception thrown for a transition firing illegally. + */ + public class IllegalTransitionFireException extends RuntimeException + { + /** + * The default serialVersionUID. + */ + private static final long serialVersionUID = 1L; + + public IllegalTransitionFireException(String message) + { + super(message); // Use the default constructor. + } + } + + /** + * Gets a set of the enabled transitions that have not yet fired. + * @return The set of the remaining transitions. + */ + public HashSet getRemainingTransitions() + { + return (HashSet) enabledTransitions.clone(); + } + + /** + * Creates an id for the base state. + */ + public void createStateId() + { + state.createId(); + } + + /** + * Overrides the toString method. + */ + @Override + public String toString() + { + String result = state.toString(); // Variable for building the string. + + // Get the remaining transitions. + result += "\n\t\tRemaining Transitions : " + enabledTransitions + "\n"; + + return result; + } + + public boolean hasMetDelay(int transition) + { + return zone.hasMetDelay(transition); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/LPNTranslator.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/LPNTranslator.java new file mode 100644 index 000000000..13eec874f --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/LPNTranslator.java @@ -0,0 +1,542 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.dbm2; +import java.util.HashMap; +import java.util.HashSet; + +import edu.utah.ece.async.lema.verification.lpn.*; + +/** + * This class mainly adds the ability to address the places and Boolean variables via + * integers instead of names, that is, an LPNBool imposes an ordering on the places and + * Boolean variables. This enables methods that ask whether the ith place is marked or + * the ith Boolean variable is true. + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class LPNTranslator{ + + private HashMap placeNames; // A dictionary to convert to the place names. + private HashMap placeIndex; // A dictionary to convert the name to the + // index in MarkedPlaces. + + private HashMap booleanNames; // A dictionary to convert to the boolean name. + private HashMap booleanIndex; // A dictionary to convert the name to the + // index in booleanValue. + + private HashMap transitionNames; // A diction to convert to the transition + //name. + private HashMap transitionIndex; // A dictionary to convert the name + // of the transition to its index. + + + private LPN lpn; // The LPN to translate between. + + /** + * Creates a translator between the names of the associated Lhpnfile and + * the indices. + * @param lpn + */ + public LPNTranslator(LPN lpn) + { + this.lpn = lpn; + createDictionaries(); // Create the dictionaries that translate between + // the names of places, transitions, etc... and + // their indexed value. + } + + /** + * Create the dictionaries to translate from the place names to their + * internal representation. + */ + private void createPlaceDictionaries() + { + // Create the dictionaries. + placeIndex = new HashMap(); + placeNames = new HashMap(); + + int i = 0; + for(String s : lpn.getPlaceList()) + { + placeIndex.put(s, i); + placeNames.put(i, s); + i++; + } + } + + /** + * Create the dictionaries to translate from the Boolean names to their + * internal representation. + */ + private void createBooleanDictionaries() + { + // Create the dictionaries. + booleanIndex = new HashMap(); + booleanNames = new HashMap(); + + int i=0; + for(String s : lpn.getBooleans().keySet()) + { + booleanIndex.put(s, i); + booleanNames.put(i, s); + i++; + } + } + + /** + * Create the dictionaries to translate from the transition names to their + * internal representation. + */ + private void createTransitionDictionaries() + { + // Create the dictionaries. + transitionIndex = new HashMap(); + transitionNames = new HashMap(); + + int i=0; + for(String s: lpn.getTransitionList()) + { + transitionIndex.put(s, i); + transitionNames.put(i, s); + i++; + } + } + + /** + * Convenience method to get the place, Boolean and transition dictionaries. + */ + private void createDictionaries() + { + createPlaceDictionaries(); + createBooleanDictionaries(); + createTransitionDictionaries(); + } + + /** + * Get the initial markings for the places. + * @return A Boolean array where the ith value is true if the ith place + * is marked, false otherwise. + */ + public boolean[] getInitialMarkings() + { + + boolean[] boolValues = new boolean[placeNames.size()]; + + for(int i=0; i currentStringBooleanValues = new HashMap(); + + for(int i=0; i 0; + } + } + + return newValues; + } + + /** + * Modifies the current markings to reflect the situation when the given transition + * fires. More specifically, this method sets the truth value to false if + * a given making is in the preset of the transition and sets the truth value to + * true if the transition is in the postset of the transition. + * @param transition The transition to fire. + * @param currentMarkings The current places that are marked. + */ + public boolean[] getNewMarking(int transition, boolean[] currentMarkings) + { + // Create a copy of the currentMarkings to return. + boolean[] newMarkings = currentMarkings.clone(); + + // Get the name of the transition that is firing. + String transitionToFire = transitionNames.get(transition); + + // If the transition does not exist, then return the given markings. + if(transitionToFire == null) + { + return newMarkings; + } + + // Get the names of the places in the preset and postset + String[] presetPlaces = lpn.getPreset(transitionToFire); + String[] postsetPlaces = lpn.getPostset(transitionToFire); + + // Remove the preset places from the marked places. + for(int i = 0; i that contains the indices of the enabled transitions. + */ + public HashSet getEnabledTransitions(boolean[] currentMarkings) + { + // Get a hash set to store the enabled transitions as they are found. + HashSet enabledTransitions = new HashSet(); + + for(String s : lpn.getTransitionList()) + { + if(isEnabled(s, currentMarkings)) + { + enabledTransitions.add(transitionIndex.get(s)); + } + } + + return enabledTransitions; + } + + + public HashSet getEnabledTransitions(LPNTransitionState state) + { + // Get a hash set to store the enabled transitions as they are found. + HashSet enabledTransitions = new HashSet(); + + for(String s : lpn.getTransitionList()) + { + if(isEnabled(s, state) && hasMetDelay(s, state)) + { + enabledTransitions.add(transitionIndex.get(s)); + } + } + + return enabledTransitions; + } + + public void getEnabledTransitions(LPNTransitionState state, HashSet enabledTransitions) + { + for(String s : lpn.getTransitionList()) + { + //if(isEnabled(s, state) && hasMetDelay(s, state)) + if(isEnabled(s, state)) + { + enabledTransitions.add(transitionIndex.get(s)); + } + } + } + + /** + * Private method that checks if a transition is enabled using the transitions + * name. + * @param transition The name of the transition to check. + * @param currentMarkings The current markings. + * @return True if the transition is enabled, false otherwise. + */ + private boolean isEnabled(String transition, boolean[] currentMarkings) + { + for(String s : lpn.getPreset(transition)) + { + // Check if the place is marked in the current marking. + if(currentMarkings[placeIndex.get(s)] != true) + { + return false; + } + } + + return true; + } + + /** + * Private method that checks if a transition is enabled using the transitions + * name. + * @param transition The name of the transition to check. + * @param currentMarkings The current markings. + * @return True if the transition is enabled, false otherwise. + */ + private boolean isEnabled(String transition, LPNTransitionState state) + { + for(String s : lpn.getPreset(transition)) + { + // Check if the place is marked in the current marking. + if(state.getState().getMarkedPlaces()[placeIndex.get(s)] != true) + { + return false; + } + } + + //return hasMetDelay(transition, state); + return true; + } + + /** + * Overrides the toString method. It prints the lexicon. + */ + @Override + public String toString() + { + String result = ""; + + // Add the places + result += placeIndex + "\n"; + + // Add the Boolean values. + result += booleanIndex + "\n"; + + // Add the transitions. + result += transitionIndex + "\n"; + + return result; + } + + /** + * Defines an exception thrown when + */ + public class UnsafeLPNException extends RuntimeException + { + /** + * The default serialVersionUID. + */ + private static final long serialVersionUID = 1L; + + public UnsafeLPNException(String message) + { + super(message); // Use the default constructor. + } + } + + private boolean hasMetDelay(String transition, LPNTransitionState state) + { + return state.hasMetDelay(transitionIndex.get(transition)); + } + + public int getDelayLowerBound(int transition, boolean[] booleanMarkings) + { + HashMap values = createBooleanHashMap(booleanMarkings); + + ExprTree exp = lpn.getDelayTree(transitionNames.get(transition)); + + if(exp.getOp() !=null && exp.getOp().equals("uniform")) + { + exp = exp.getLeftChild(); + return -1*(int) exp.evaluateExpr(values); + } + return -1 *(int) exp.evaluateExpr(values); + } + + private HashMap createBooleanHashMap(boolean[] booleanMarkings) + { + HashMap values = new HashMap(); + + for(int i=0; i values = createBooleanHashMap(booleanMarkings); + + ExprTree exp = lpn.getDelayTree(transitionNames.get(transition)); + + if(exp.getOp() !=null && exp.getOp().equals("uniform")) + { + exp = exp.getRightChild(); + return (int) exp.evaluateExpr(values); + } + return (int) exp.evaluateExpr(values); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/README.txt b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/README.txt new file mode 100644 index 000000000..2938fcbea --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/README.txt @@ -0,0 +1,5 @@ +My program can be run by selecting the DBM2 radio button in the verification view. +The resulting files are a name.dot file and a name.txt file in the verification's standard folder +where name is the name of the name is the Verification ID. +In the subfolder TestFiles of the folder test, are a few test lpn files that I used for testing my +program. \ No newline at end of file diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/StateExploration.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/StateExploration.java new file mode 100644 index 000000000..7f298d862 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/dbm2/StateExploration.java @@ -0,0 +1,370 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.dbm2; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.PrintStream; +import java.util.*; + +import javax.swing.JFileChooser; + +import edu.utah.ece.async.ibiosim.dataModels.util.exceptions.BioSimException; +import edu.utah.ece.async.lema.verification.lpn.*; +import edu.utah.ece.async.lema.verification.timed_state_exploration.dbm2.LPNTranslator.UnsafeLPNException; + +/** + * This class finds the state graph for an LPN from an LPNFile object. + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class StateExploration { + + + HashMap placeNames; // A dictionary to convert to the place names. + HashMap placeIndex; // A dictionary to convert the name to the index + // in MarkedPlaces. + + HashMap booleanNames; // A dictionary to convert to the boolean name. + HashMap booleanIndex; // A dictionary to convert the name to the index + // in booleanValue. + + ArrayList States; // Holds the states found so far. + + public static void main(String[] args) throws FileNotFoundException, BioSimException + { + // Set up the path for where to store the resulting files. + String workingDirectory = System.getProperty("user.dir"); + String testFolder = workingDirectory + + "\\gui\\src\\verification\\timed_state_exploration\\test\\"; + + // Create the printStreams for the dot file and log file. + PrintStream dotFile = new PrintStream(testFolder + "OutPutTestFiles\\testDot.dot"); + PrintStream logFile = new PrintStream(testFolder + "OutPutTestFiles\\testLog.txt"); + + // Set up a file chooser to get the the lpn file to explore. + JFileChooser fc = new JFileChooser(); + + fc.setCurrentDirectory(new File(testFolder + "TestFiles")); + + // Launch the file chooser and get the file. + int returnval = fc.showOpenDialog(null); + if(returnval == JFileChooser.APPROVE_OPTION){ + + // Extract the file chosen. + File fileName = fc.getSelectedFile(); + + // Create the LhpnFile object and load it with the file. + LPN lpn = new LPN(); + lpn.load(fileName.getAbsolutePath()); + + // Run the state exploration algorithm which will produce a log file. + //ArrayDeque statesFound = exploreStateGraph(lpn, logFile); + Collection statesFound = exploreStateGraph(lpn, logFile); + + + printDotFile(statesFound, dotFile); + } + else + { + + } + + } + + + public static void findStateGraph(LPN lpn, String directory, String fileName) + throws FileNotFoundException + { + // Create the printStreams for the dot file and log file. + + String name = fileName.replace("lpn", "txt"); + + PrintStream logFile = new PrintStream(directory + name); + + + + // Run the state exploration algorithm which will produce a log file. + //ArrayDeque statesFound = exploreStateGraph(lpn, logFile); + Collection statesFound = exploreStateGraph(lpn, logFile); + + logFile.close(); + + //PrintStream dotFile = new PrintStream(directory + fileName.replace("lpn", "dot")); + PrintStream dotFile = new PrintStream(directory + "Graphof" + name.replace("txt", "dot")); + printDotFile(statesFound, dotFile); + dotFile.close(); + + } + + /** + * Create the dictionaries to translate from the place names to their + * internal representation. + * @param lpn The associated LHPN + */ + private void createPlaceDictionaries(LPN lpn) + { + int i = 0; + for(String s : lpn.getPlaceList()) + { + placeIndex.put(s, i); + placeNames.put(i, s); + i++; + } + } + + /** + * Create the dictionaries to translate from the Boolean names to their + * internal representation. + * @param lpn + */ + private void createBooleanDictionaries(LPN lpn) + { + int i=0; + for(String s : lpn.getBooleans().keySet()) + { + booleanIndex.put(s, i); + booleanNames.put(i, s); + i++; + } + } + + /** + * Convenience method to get both the place and Boolean dictionaries. + * @param lpn + */ + @SuppressWarnings("unused") + private void createDictionaries(LPN lpn) + { + createPlaceDictionaries(lpn); + createBooleanDictionaries(lpn); + } + +// private static ArrayDeque exploreStateGraph(LhpnFile lpn, PrintStream writer) + private static Collection exploreStateGraph(LPN lpn, PrintStream writer) + { + // Stacks for the states remaining to explore and the states that are found. + ArrayDeque statesToExplore = new ArrayDeque(); + //ArrayDeque statesFound = new ArrayDeque(); + HashMap statesFound = new HashMap(); + + LPNTranslator transLPN = new LPNTranslator(lpn); + + // Print the lexicon. + writer.println(transLPN); + + // Set the initial place markings. + // Set the initial boolean markings. + // Set the initial state space + LPNTransitionState currentState = new LPNTransitionState(transLPN); + + // TODO Change finding enabled transitions to new methods. + + // Get the initial set of enabled transitions. + currentState.initializeEnabledTransitions(transLPN); + + // Create an id for the first state. + currentState.createStateId(); + + // Print the initial state. + writer.println("The initial state is: " + currentState); + + // Set the done flag + boolean done = false; + + // Add initial state to found states. + //statesFound.add(currentState.getState()); + statesFound.put(currentState.getState(), currentState.getState()); + + // Loop until done is true. + while (!done) + { + // Check if there are transitions to fire. If not + // then this path has hit a dead end. + if(!currentState.remainingTransitions()) + { + // check if the stack is empty + if(!statesToExplore.isEmpty()) + { + // if not, pop the first record and make that the new state + // to explore from. + currentState = statesToExplore.pop(); + writer.println("I have reach a dead end and am going back to State " + + currentState.getState().getId()); + continue; + } + // if it is empty, break out of the loop. + break; + } + // Get an enabled transition + int transition = currentState.getATransition(); + + // if there are still enabled transitions, push + // them on the stack for later + if(currentState.remainingTransitions()) + { + statesToExplore.push(currentState); + } + + writer.println("I am firing transition " + transLPN.getTransitionName(transition)); + + // Update the markings in a new variable + // Update the boolean values in a new variable + LPNState nextState; + HashSet enabledTransitions = new HashSet(); + try + { + nextState = currentState.getUpdatedState(transition, transLPN, + enabledTransitions); + } + catch(UnsafeLPNException e) + { + writer.println(e.getMessage()); + //return statesFound; + return statesFound.keySet(); + } + + writer.println("State found\n"); + // If the new state is not one seen before + //if(!statesFound.contains(nextState)) + if(!statesFound.keySet().contains(nextState)) + { + writer.println("State not found before. Adding to states."); + + // create an id for this state + nextState.createId(); + + // add it to the set of states + //statesFound.add(nextState); + statesFound.put(nextState, nextState); + + // add the appropriate edge + currentState.getState().addNextState(nextState); + + nextState.addPreviousState(currentState.getState()); + + // TODO create a constructor that takes the enabled transitions. + // and use is here. Then eliminate the initializeEnabledTransitions + // step. + + currentState = new LPNTransitionState(nextState, enabledTransitions); + + // make this state the new state to explore from. + //currentState = new LPNTransitionState(nextState); + + + // Get the new set of enabled transitions. + //currentState.initializeEnabledTransitions(transLPN); + + writer.println(currentState); + + } + // If the new state is one seen before + else{ + writer.println("State found before." + statesFound.get(nextState)); + + //if(checkBooleanArrays()) + + // Get the previous found state's object for adding edges. + LPNState previousFoundState = statesFound.get(nextState); + + // Add edges. + currentState.getState().addNextState(previousFoundState); + previousFoundState.addPreviousState(currentState.getState()); + + + // check if the stack is empty + if(!statesToExplore.isEmpty()) + { + // if not, pop the first record and make that the new state + // to explore from. + currentState = statesToExplore.pop(); + writer.println("I am going back to state " + currentState.getState().getId()); + } + // if it is empty, set the done flag to true. + else + { + done = true; + } + } + + } + + // Return the set of states. + //return statesFound; + return statesFound.keySet(); + } + + /** + * Checks if the two arrays are equal. + * @param array1 + * @param array2 + * @return True if the two arrays are equal, false otherwise. + */ + @SuppressWarnings("unused") + private static boolean checkBooleanArrays(boolean[] array1, boolean[] array2) + { + if(array1 == null) + { + return array2 == null; + } + else if(array1.length == 0) + { + return array2.length == 0; + } + + for(int i=0; i states, PrintStream writer) + private static void printDotFile(Collection states, PrintStream writer) + { + // Print the opening header for the dot file. + writer.println("digraph G {"); + + for(LPNState s : states) + { + try{ + System.out.println(s); + } + catch(Exception e){ + + } + + for(LPNState nextS : s.getNextStates()) + { + writer.println("\t\"S " + s.getId() +LPNState.getStringArray(s.getBooleanValues()) + + "\" -> \"S " + nextS.getId() + + LPNState.getStringArray(nextS.getBooleanValues()) + "\""); + } + } + + writer.print("}"); + } +} \ No newline at end of file diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/octagon/Equivalence.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/octagon/Equivalence.java new file mode 100644 index 000000000..3b879d5fa --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/octagon/Equivalence.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.octagon; + +import java.util.Collection; +import java.util.HashSet; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LpnTranList; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.ContinuousRecordSet; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.EventSet; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.IntervalPair; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.LPNContinuousPair; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.LPNTransitionPair; + +/** + * The purpose of this interface is to define the methods of Zones + * Octagons that other classes use. + * + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public interface Equivalence { + + public IntervalPair getContinuousBounds(String variable, LPN lhpn); + + public int getCurrentRate(LPNTransitionPair index); + + public int timerIndexToDBMIndex(LPNTransitionPair index); + + public int getUpperBoundTrue(int index); + + public int getUnwarpedUpperBound(LPNContinuousPair lcpair); + + public int getLowerBoundTrue(int index); + + public LPN[] get_lpnList(); + + public int getDbmEntry(int i, int j); + + public int getIndexByTransitionPair(LPNTransitionPair ltPair); + + public int getVarIndex(int lpnIndex, String name); + + public int getLowerBoundbyTransition(Transition t); + + public Collection getEnabledTransitions(); + + public Collection getEnabledTransitions(int lpnIndex); + + public boolean subset(Equivalence equivalence); + + public boolean superset(Equivalence equivalence); + + public Collection getPossibleEvents(int lpnIndex, + State state); + + public Equivalence fire(Transition firedTran, + LpnTranList enabledTransitions, + ContinuousRecordSet newAssignValues, State[] newStates); + + public Equivalence getContinuousRestrictedZone(EventSet eventSet, + State[] states); + + public void recononicalize(); + + public void advance(State[] states); + + public Equivalence resetRates(); + + public Equivalence addTransition(HashSet newlyEnabled, + State[] states); + + public Equivalence fire(LPNTransitionPair firedRate, int currentRate); + + public Equivalence moveOldRateZero(LPNContinuousPair firedRate); + + public Equivalence saveOutZeroRate(LPNContinuousPair firedRate); + + public Equivalence clone(); + + public void setCurrentRate(LPNTransitionPair firedRate, int currentRate); + + public void dbmWarp(Equivalence equivalence); + + public int getDbmEntryByPair(LPNTransitionPair zeroTimerPair, + LPNTransitionPair index); + + public IntervalPair getRateBounds(LPNTransitionPair contVar); + + public IntervalPair getContinuousBounds(LPNContinuousPair contVar); + + public int rateResetValue(LPNTransitionPair contVar); +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/octagon/Octagon.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/octagon/Octagon.java new file mode 100644 index 000000000..c3c0c94d0 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/octagon/Octagon.java @@ -0,0 +1,5528 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.octagon; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import edu.utah.ece.async.lema.verification.lpn.ExprTree; +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.lpn.Variable; +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.platuLpn.DualHashMap; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LpnTranList; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.ContinuousRecordSet; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.ContinuousUtilities; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.Event; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.EventSet; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.InequalityVariable; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.IntervalPair; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.LPNContAndRate; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.LPNContinuousPair; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.LPNTransitionPair; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.UpdateContinuous; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.VariableRangePair; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.Zone; + +/** + * Octagons ('The Octagon Abstract Domain' by Mine) are the subsets of + * Euclidean space formed by intersecting hyperplanes associated with + * equations of the form vi-vj<=a, vi+vj<=a, and -vi-vj<=a. In two + * dimensions, they correspond to convex polygons with up to eight + * sides where each side is parallel to an axis, forms a positive + * 45 degree angle with the axes, or forms a negative 45 degree angle + * with the the axes. + * + * Octagons, like zones, can be represented by a difference bound + * matrix (DBM). For an octagon in n-dimensions given by the + * variables v0, v1, ..., v(n-1), the DBM uses 2n-dimensions given by + * v0+, v0-, v1+, v1-, ..., v(n-1)+, v(n-1)-. The variables are connected + * by vi+ = +vi and vi- = -vi. Thus vi+ represents the positive + * vi and vi- represents the negative vi. Given the matrix + * + * v0+ v0- v1+ v1- ... v(n-1)+ v(n-1)- + * v0+ m00 m01 m02 m03 ... m(0,2n-2) m(0,2n-1) + * v0- m10 m11 m12 m13 ... m(1,2n-2) m(1,2n-1) + * v1+ m20 m21 m22 m23 ... m(2,2n-2) m(2,2n-1) + * v1- m30 m31 m32 m33 ... m(3,2n-2) m(3,2n-1) + * ... ... ... ... ... ... .... .... + * v(n-1)+ m(2n-2,0) m(2n-2,1) m(2n-2,2) m(2n-2,3) ... m(2n-2,2n-2) m(2n-2,n-1) + * v(n-1)- m(2n-1,0) m(2n-1,1) m(2n-1,2) m(2n-1,3) ... m(2n-1,2n-2) m(2n-1,n-1) + * + * the inequalities are encoded as vi - vj <= mji. So an entry gives + * the upper bound for the column minus the row. So, for example, + * v0- - v0+ <= m01. Removing the plus and minus variables, the inequality is + * actually -v0-v0 <= m01 or -2v0 <= m01. So m01 is the negative of twice the + * lower bound of v0. + * + * For a more concrete example, let a two dimensional octagon be defined as the + * intersection of the spaces defined inequalities mx <= x <= Mx, + * my <= y <= My, y-x <= b1, y-x <= -b2, y+x <= b3, and -y-x <= -b4 + * then the DBM is given by + * + * x+ x- y+ y- + * x+ 0 -2mx b1 -b4 + * x- 2Mx 0 b3 -b2 + * y+ -b2 -b4 0 -2my + * y- b3 b1 2My 0 + * + * The b1, b2, b3, and b4 are the y-intercepts of the boundary lines + * for the cross inequalities, the inequalities involving both x and y. + * + * + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Octagon implements Equivalence { + + /* + * The list of LPN for the variables. + */ + private LPN[] _lpnList; + + /* + * The matrix for storing the DBM. + */ + private int[][] _matrix; + + /* + * Stores the timers and the non-rate-zero + * continuous variables. An LPNTransitionPair + * gives the integer representation of the + * variables. The position of the variables in + * this list gives their order in the DBM. The + * i-th variable vi has vi+ at 2i and vi- at + * 2i+1. The index of the variable in this list + * is referred to in this class as the base + * index. + */ + private LPNTransitionPair[] _dbmVarList; + + /* + * These two array stores the cached min,max values for timers and + * the range of rates for non-zero rate continuous variables. I could + * add an additional row and column to the DBM the same as in the + * case of the Zone, but it is a little tedious to have to keep + * adjusting for the difference this makes for the indecies. + * The _upperBounds stores twice the maximum and the _lowerBounds + * stores twice the negative of the minimum. + */ + private int[] _upperBounds; + private int[] _lowerBounds; + + + /* + * Stores the continuous variables that have rate zero. A zero rate + * variable still has a potential range of rates and a range of + * values. The LPNConAnd Rate keeps the range of rates information + * and the VariableRangePair keeps the range of values. This extra + * information about the range of values is not needed for a + * variable with a non-zero rate since the DBM stores this + * information. + */ + DualHashMap _rateZeroContinuous; + + /* + * Turns on and off subsets for the zones. + * True means subset will be considered. + * False means subsets will not be considered. + */ + private static boolean _subsetFlag = true; + + /* + * Turns on and off supersets for zones. + * True means that supersets will be considered. + * False means that supersets will not be considered. + */ + private static boolean _supersetFlag = true; + + + /* Write a log file */ + private static BufferedWriter _writeLogFile = null; + + + /* The hash code. A -1 value is used to indicate the + * hashcode has not been created yet. + */ + private int _hashCode; + + /** + * Returns the write log. + * @return + * The _writeLogfile. + */ + public static BufferedWriter get_writeLogFile(){ + return _writeLogFile; + } + + /** + * Sets the BufferedWriter. + * @param writeLogFile + */ + public static void set_writeLogFile(BufferedWriter writeLogFile){ + _writeLogFile = writeLogFile; + } + + + /** + * Sets the writeLogFile to null. + */ + public static void reset_writeLogFile(){ + _writeLogFile = null; + } + + /** + * Gets the value of the subset flag. + * @return + * True if subsets are requested, false otherwise. + */ + public static boolean getSubsetFlag(){ + return _subsetFlag; + } + + /** + * Sets the value of the subset flag. + * @param useSubsets + * The value for the subset flag. Set to true if + * supersets are to be considered, false otherwise. + */ + public static void setSubsetFlag(boolean useSubsets){ + _subsetFlag = useSubsets; + } + + /** + * Gets the value of the superset flag. + * @return + * True if supersets are to be considered, false otherwise. + */ + public static boolean getSupersetFlag(){ + return _supersetFlag; + } + + /** + * Sets the superset flag. + * @param useSupersets + * The value of the superset flag. Set to true if + * supersets are to be considered, false otherwise. + */ + public static void setSupersetFlag(boolean useSupersets){ + _supersetFlag = useSupersets; + } + + /** + * Zero argument constructor for use in methods that create Octagons where + * the members variables will be set by the method. + */ + protected Octagon() + { + //*_matrix = new int[0][0]; + //*_indexToTimerPair = new LPNTransitionPair[0]; + + //*_hashCode = -1; + _hashCode = -1; + + //*_lpnList = new LhpnFile[0]; + + + //*_rateZeroContinuous = new DualHashMap(); + _rateZeroContinuous = new DualHashMap(); + + } + + /** + * Creates an octagon based on the local states. + * @param localStates + * The current state (or initial) of the LPNs. + */ + public Octagon (State[] localStates){ + + // Open the log file. + if(_writeLogFile == null && Options.get_TimingLogfile() != null){ + try{ + _writeLogFile = + new BufferedWriter( + new FileWriter(Options.get_TimingLogfile())); + } catch (IOException e) { + + e.printStackTrace(); + }finally{ + + } + } + + // Initialize hash code to -1 (indicating nothing cached). + _hashCode = -1; + + // Initialize the LPN list. + //* Zone.initialize_lpnList(localStates); + initialize_lpnList(localStates); + + // Get the enabled transitions. This initializes the _indexTotimerPair + // which stores the relevant information. + // This method will also initialize the _rateZeroContinuous + //* Zone.initialize_indexToTimerPair(localStates); + /* + * Get the enabled transitions. This initializes the _dbmVarList + * which stores the relevant information. + * This method will also initialize the _rateZeroContinuous + * variable. + */ + initialize_dbmVarList(localStates); + + + /* + * Initialize the matrix. + * Note: in contrast with the Zone, the _matrix in an Octagon + * is only the DBM. + */ + //* Zone._matrix = new int[matrixSize()][matrixSize()]; + _matrix = new int[DBMsize()][DBMsize()]; +// _lowerBounds = new int[DBMsize()]; +// _upperBounds = new int[DBMsize()]; + _lowerBounds = new int[_dbmVarList.length]; + _upperBounds = new int[_dbmVarList.length]; + +// this.toString(); + // Set the lower bound/ upper bounds of the timers and the rates. + //* Zone.initializeLowerUpperBounds(getAllNames(), localStates); + initializeLowerUpperBounds(getAllNames(), localStates); + + // Initialize the row and column entries for the continuous variables. + //* zone.initializeRowColumnContVar(); + initializeRowColumnContVar(); + + + // Create a previous zone to the initial zone for the sake of warping. + //* Zone.Zone tmpZone = beforeInitialZone(); + Octagon tmpOct = beforeInitialOctagon(); + + //* Zone.dbmWarp(tmpZone); + dbmWarp(tmpOct); + + //* Zone.recononicalize(); + recononicalize(); + + // Advance Time + //* Zone.advance(localStates); + advance(localStates); + + // Re-canonicalize + //* Zone.recononicalize(); + recononicalize(); + + // Get the amount of time that has + // advanced. If there is a variable in the octagon. + if(this._dbmVarList.length != 0){ + + // Get the max value of the first + // entry for calculating how + // much time has advanced. + int initial = getUpperBound(0); + + + int time = (int)Math.ceil((this.getUpperBound(0) - initial)/2); + + adjustB3(this, time); + } + + // Check the size of the DBM. + //* Zone.checkZoneMaxSize(); + } + + /** + * Creates an Octagon based on the local states. + * @param localStates + * The current state (or initial) of the LPNs. + * @param init + * Should be true if this is and initial octagon. + */ + public Octagon(State[] localStates, boolean init) { + // Extract the local states. + //State[] localStates = tps.toStateArray(); + + // Initialize hash code to -1 (indicating nothing cached). + _hashCode = -1; + + // Initialize the LPN list. + initialize_lpnList(localStates); + + // Get the enabled transitions. This initializes the _indexTotimerPair + // which stores the relevant information. + // This method will also initialize the _rateZeroContinuous + //*initialize_indexToTimerPair(localStates); + initialize_dbmVarList(localStates); + + // Initialize the matrix. + //*_matrix = new int[matrixSize()][matrixSize()]; + _matrix = new int[DBMsize()][DBMsize()]; + _lowerBounds = new int[_dbmVarList.length]; + _upperBounds = new int[_dbmVarList.length]; + + // Set the lower bound/ upper bounds of the timers and the rates. + initializeLowerUpperBounds(getAllNames(), localStates); + + // Initialize the row and column entries for the continuous variables. + initializeRowColumnContVar(); + + if(init){ + return; + } + + // Advance Time + //advance(); + advance(localStates); + + // Re-canonicalize + recononicalize(); + + // Check the size of the DBM. + //*checkZoneMaxSize(); + } + + /** + * This method creates an Octagon identical to the current Octagon + * except all the current rates are turned to 1. This is to provide + * a previous Octagon to the initial Octagon for warping. + * @return + * A Octagon identical to this Octagon with all rates set to 1. + */ + private Octagon beforeInitialOctagon(){ + + //*Zone z = this.clone(); + Octagon oct = this.clone(); + + //*for(int i=1; i(); + + // Initialize the _rateZeroContinuous variables. + _rateZeroContinuous = + new DualHashMap(); + + // This list accumulates the transition pairs (ie timers) and the continuous + // variables. + //*ArrayList enabledTransitionsArrayList = + //* new ArrayList(); + + // This list accumulates the transition pairs, that is the timers, and the + // continuous variables + ArrayList enabledTransitionsArrayList = + new ArrayList(); + + // Put in the zero timer. + //*enabledTransitionsArrayList + //*.add(new LPNTransitionPair(LPNTransitionPair.ZERO_TIMER, + //* LPNTransitionPair.ZERO_TIMER)); + + + // We do not need to put in the zero timer for Octagons. + + // Get the continuous variables. + //*for(int i=0; i singleLPN = + //* new ArrayList(); + + // Accumulates the changing continuous variables for a single LPN. + ArrayList singleLPN = + new ArrayList(); + + // Get the associated LPN. + //*LhpnFile lpn = localStates[i].getLpn(); + + // Get the associated LPN. + LPN lpn = localStates[i].getLpn(); + + // Get the continuous variables for this LPN. + //*String[] continuousVariables = lpn.getContVars(); + + // Get the continuous variables for this LPN. + String[] continuousVariables = lpn.getContVars(); + + // Get the variable, index map. + //*DualHashMap variableIndex = lpn.getContinuousIndexMap(); + + // Get the variables, index map. + DualHashMap variableIndex = lpn.getContinuousIndexMap(); + + + // Find which have a nonzero rate. + //*for(int j=0; j singleLPN = new ArrayList(); + + // Accumulates the transition pairs for one LPN. + ArrayList singleLPN = new ArrayList(); + + // The index of the boolean value corresponds to the index of the Transition. + //* for(int j=0; j= 0){ + setMin(i, ContinuousUtilities.chkDiv(bound.get_LowerBound(), range.get_LowerBound(), false)); + setMax(i, ContinuousUtilities.chkDiv(bound.get_UpperBound(), range.get_LowerBound(), true)); + } + else{ + setMax(i, ContinuousUtilities.chkDiv(bound.get_LowerBound(), range.get_LowerBound(), true)); + setMin(i, ContinuousUtilities.chkDiv(bound.get_UpperBound(), range.get_LowerBound(), false)); + } + } + //*} + //*else{ + else{ + + // Get the expression tree. + //*ExprTree delay = _lpnList[ltPair.get_lpnIndex()].getDelayTree(varNames[i]); + ExprTree delay = _lpnList[ltPair.get_lpnIndex()].getDelayTree(varNames[i]); + + + // Get the values of the variables for evaluating the ExprTree. + //*HashMap varValues = + //* _lpnList[ltPair.get_lpnIndex()] + //* .getAllVarsWithValuesAsString(localStates[ltPair.get_lpnIndex()].getVariableVector()); + HashMap varValues = + _lpnList[ltPair.get_lpnIndex()] + .getAllVarsWithValuesAsString( + localStates[ltPair.get_lpnIndex()].getVariableVector()); + + + // Set the upper and lower bound. + // Passing the Octagon as null since it should not be needed. + //*range = delay.evaluateExprBound(varValues, this, null); + range = delay.evaluateExprBound(varValues, this, null); + + } + //*} + + //*setLowerBoundbydbmIndex(i, range.get_LowerBound()); + //*setUpperBoundbydbmIndex(i, range.get_UpperBound()); + + /* + * Set the lower and upper bounds on the timer delays and + * range of rates. + */ + _lowerBounds[i] = -1*range.get_LowerBound(); + _upperBounds[i] = range.get_UpperBound(); + + //*} + } + } + + /** + * Gives the names of all the transitions and continuous variables that + * are represented by the zone. + * @return + * The names of the transitions and continuous variables that are + * represented by the zone. + */ + public String[] getAllNames(){ + + /* + * This code can be made more efficient + * by combining the getContVarNames and + * getTranNames. + */ + + + // Get the continuous variable names. + //*String[] contVar = getContVarNames(); + String[] contVar = getContVarNames(); + + + // Get the transition names. + //*String[] trans = getTranNames(); + String[] trans = getTranNames(); + + // Create an array large enough for all the names. + //*String[] names = new String[contVar.length + trans.length + 1]; + String[] names = new String[contVar.length + trans.length]; + + // Add the zero timer. + //*names[0] = "The zero timer."; + + // Add the continuous variables. + //*for(int i=0; i contNames = new ArrayList(); + ArrayList contNames = new ArrayList(); + + + // Find the pairs that represent the continuous variables. Loop starts at + // i=1 since the i=0 is the zero timer. + //*for(int i=1; i<_indexToTimerPair.length; i++){ + for (int i=0; i<_dbmVarList.length; i++){ + + //*LPNTransitionPair ltPair = _indexToTimerPair[i]; + LPNTransitionPair ltPair = _dbmVarList[i]; + + // If the isTimer value is false, then this pair represents a continuous + // variable. + // If pair is LPNContinuousPair. + //*if(ltPair instanceof LPNContinuousPair){ + if(ltPair instanceof LPNContinuousPair){ + // Get the LPN that this pairing references and find the name of + // the continuous variable whose index is given by this pairing. + //*contNames.add(_lpnList[ltPair.get_lpnIndex()] + //* .getContVarName(ltPair.get_transitionIndex())); + contNames.add(_lpnList[ltPair.get_lpnIndex()] + .getContVarName(ltPair.get_transitionIndex())); + + } + //*} + //*} + } + + //*return contNames.toArray(new String[0]); + return contNames.toArray(new String[0]); + } + + /** + * Gets the names of the transitions that are associated with the timers in the + * Octagon. + * @return + * The names of the transitions whose timers are in the Octagon. + */ + public String[] getTranNames(){ + + // List for accumulating the names. + //*ArrayList transitionNames = new ArrayList(); + ArrayList transitionNames = new ArrayList(); + + // Find the pairs that represent the transition timers. + //*for(int i=1; i<_indexToTimerPair.length; i++){ + for (int i=0; i<_dbmVarList.length; i++){ + + //*LPNTransitionPair ltPair = _indexToTimerPair[i]; + LPNTransitionPair ltPair = _dbmVarList[i]; + + // If this is an LPNTransitionPair and not an LPNContinuousPair + //*if(!(ltPair instanceof LPNContinuousPair)){ + if(!(ltPair instanceof LPNContinuousPair)){ + + // Get the LPN that this pairing references and find the name of the + // transition whose index is given by this pairing. + //*transitionNames.add(_lpnList[ltPair.get_lpnIndex()] + //*.getTransition(ltPair.get_transitionIndex()).getLabel()); + transitionNames.add(_lpnList[ltPair.get_lpnIndex()] + .getTransition(ltPair.get_transitionIndex()).getLabel()); + + //*} + } + //*} + } + + //*return transitionNames.toArray(new String[0]); + return transitionNames.toArray(new String[0]); + } + + /** + * Initialize the rows and columns for the continuous variables. + */ + private void initializeRowColumnContVar(){ + + + // The only entries that do not need to be checked are the ones where both variables + // represent timers. + + //*for(int row=2; row<_indexToTimerPair.length; row++){ + for (int rowBase=1; rowBase<_dbmVarList.length; rowBase++){ + // Note: rowBase is indexing the pos and neg variables + // for the row. + + //*LPNTransitionPair ltRowPair = _indexToTimerPair[row]; + LPNTransitionPair ltRowPair = _dbmVarList[rowBase]; + + //*for(int col=1; col rowBase is equal to an entry defined by + * colBase > rowBase. The condition is that m_(i,j) = m_(ibar,jbar). + */ + + // The new (col, row) entry. + //*int colRow = getDbmEntry(col, 0) + getDbmEntry(0, row); + +// this.toString(); + +// int colP_rowP = twiceMax(colBase) - twiceMin(rowBase); +// int colP_rowN = twiceMax(colBase) + twiceMax(rowBase); +// int colN_rowP = -1*twiceMin(colBase) - twiceMin(rowBase); +// int colN_rowN = -1*twiceMin(colBase) + twiceMax(rowBase); + + int colM_rowm = ContinuousUtilities.chkDiv( + twiceMax(colBase) - twiceMin(rowBase), 2, true); + int colM_rowM = ContinuousUtilities.chkDiv( + twiceMax(colBase) + twiceMax(rowBase), 2, true); + int colm_rowm = ContinuousUtilities.chkDiv( + -1*twiceMin(colBase) - twiceMin(rowBase), 2, true); + int colm_rowM = ContinuousUtilities.chkDiv( + -1*twiceMin(colBase) + twiceMax(rowBase), 2, true); + + //*setDbmEntry(row, col, rowCol); + //*setDbmEntry(col, row, colRow); + + _matrix[baseToPos(rowBase)][baseToPos(colBase)] = colM_rowm; + _matrix[baseToNeg(colBase)][baseToNeg(rowBase)] = colM_rowm; + + _matrix[baseToNeg(rowBase)][baseToPos(colBase)] = colM_rowM; + _matrix[baseToNeg(colBase)][baseToPos(rowBase)] = colM_rowM; + + _matrix[baseToPos(rowBase)][baseToNeg(colBase)] = colm_rowm; + _matrix[baseToPos(colBase)][baseToNeg(rowBase)] = colm_rowm; + + _matrix[baseToNeg(rowBase)][baseToNeg(colBase)] = colm_rowM; + _matrix[baseToPos(colBase)][baseToPos(rowBase)] = colm_rowM; + + } + //*} + //*} + } + } + + + /** + * Give the upper and lower bounds for a continuous variable. + * Value comes back not warped. + * @param contVar + * The variable of interest. + * @return + * The upper and lower bounds according to the octagon. Note: the + * value may be an over-approximation since an octagon stores twice + * the max and min, so one needs to adjust the division by 2 to an integer. + */ + @Override + public IntervalPair getContinuousBounds(String contVar, LPN lpn){ + + // Extract the necessary indecies. + int lpnIndex = lpn.getLpnIndex(); + + // Get the index of the continuous variable. + DualHashMap variableIndecies = lpn.getContinuousIndexMap(); + int contIndex = variableIndecies.get(contVar); + + // Package the indecies with false indicating not a timer. + // Note: setting the current rate is not necessary here since the + // LPNContinuousPair is only being used as an index. + LPNContinuousPair index = new LPNContinuousPair(lpnIndex, contIndex); + + // Search for the continuous variable in the rate zero variables. + VariableRangePair pairing = _rateZeroContinuous + .get(new LPNContAndRate(index, new IntervalPair(0,0))); + + // If Pairing is not null, the variable was found and return the result. + if(pairing != null){ + return pairing.get_range(); + } + + // If Pairing was null, the variable was not found. Search for the variable + // in the zone portion. + int base = Arrays.binarySearch(_dbmVarList, index); + + // If base < 0, the search was unsuccessful, so scream. + if(base < 0){ + throw new IllegalArgumentException("Atempted to find the bounds for " + + "a non-rate zero continuous variable that was not found in the " + + "zone."); + } + + // Else find the upper and lower bounds. + //* int lower = (-1)*getDbmEntry(i, 0); + //* int upper = getDbmEntry(0, i); +// double preupper = (double) twiceMax(base)*getCurrentRate(base); +// double prelower = (double) twiceMin(base)*getCurrentRate(base); + + double preupper = (double) twiceMax(base); + double prelower = (double) twiceMin(base); +// + int upper = (int) Math.ceil(preupper/2); + int lower = (int) Math.floor(prelower/2); + + return new IntervalPair(lower, upper); + } + + /** + * Gets twice the max of a variable. + * @param base The index of the variable pair in + * the Octagon. + * @return The maximum for the variable. + */ + private int twiceMax(int base){ + + // The maximum is given by v+ - v- <= value. So this + // is the column for the associated positive + // variable and the row of the associated + // negative variable. + + return _matrix[baseToNeg(base)][baseToPos(base)]; + } + + /** + * Sets the DBM entry for the maximum value. + * @param base The index for the variable. + * @param vlaue The value for the maximum. + */ + private void setMax(int base, int value){ + /* + * Twice the maximum value for an + * Octagon is put in the column v+ and + * row v-, since this entry is + * v+ - v- <= 2*max. + */ + _matrix[baseToNeg(base)][baseToPos(base)] = 2*value; + } + + /** + * Gets the DBM entry for the minimum value. + * @param base The base index for the minimum. + * @return Twice the minimum value. + */ + private int twiceMin(int base){ + // The minimum is given by (-1)*(v- - v+) >= (-1)*value. + // This is the negative variable column and the positive + // variable row. + return -1*_matrix[baseToPos(base)][baseToNeg(base)]; + } + + /** + * Sets the DBM entry for the minimum value. + * @param base The index for the variable. + * @param value The value for the minimum. + */ + private void setMin(int base, int value){ + /* + * Twice the minimum value for an + * Octagon is put in the column v- and + * the row v+, since this entry is + * v- - v+ <= -2*min. + */ + _matrix[baseToPos(base)][baseToNeg(base)] = -2*value; + } + + /** + * Gets the range for the continuous variable. Values come back not + * warped. + * @param ltContPair + * The index of the variable of interest. + * @return + * The range of the continuous variable described by ltContPair. + */ + @Override + public IntervalPair getContinuousBounds(LPNContinuousPair ltContPair){ + + // First check if the variable is in the DBM portion of the + // Octagon. + int variableIndex = Arrays.binarySearch(_dbmVarList, ltContPair); + + if(variableIndex < 0){ + // The variable was not found in the zone. Check to see if its + // in the rate-zero variables. Technically I will return whatever + // is in the _rateZeroConintuous, null or not. + // Of course, it will be non-null unless something has gone + // wrong since every continuous variable either has a zero + // or non-zero rate so should be either in the + + // First get an object to reference into the _rateZeroContinuous + LPNContAndRate lcr = new LPNContAndRate(ltContPair, + new IntervalPair(0,0)); + return _rateZeroContinuous.get(lcr).get_range(); + } + + // The variable was found in the Octagon. Yay. + int lower = (int) Math.floor(twiceMin(variableIndex) + *getCurrentRate(variableIndex)/2); + int upper = (int) Math.ceil(twiceMax(variableIndex) + *getCurrentRate(variableIndex)/2); + + if(getCurrentRate(ltContPair)<0){ + int tmp = lower; + lower = upper; + upper = tmp; + } + + return new IntervalPair(lower, upper); + } + + /** + * Gets the current rate for the baseIndex-th variable. Note: this is + * getting the current rate of a non-zero rate continuous variable. + * + * @param baseIndex The index of the variable to get the current rate for. + * + * @return The rate of the variable that is baseIndex in the list. It is + * assumed that index baseIndex is a continuous variable in the Octagon. + * If it is not, a cast exception is thrown. + */ + public int getCurrentRate(int baseIndex){ + + // Cast the variable as a continuous variable. + LPNTransitionPair ltPair = _dbmVarList[baseIndex]; + LPNContinuousPair lcPair = (LPNContinuousPair) ltPair; + + return lcPair.getCurrentRate(); + + } + /** + * Gets the range of the rate associated with a continuous variable. + * @param ltContPair + * The index of the continuous variable. + * @return + * The range of rates associated with the continuous variable indexed + * by ltContPair. + */ + @Override + public IntervalPair getRateBounds(LPNTransitionPair ltPair){ + + int upper; + int lower; + + // Check if the ltContpair is in the zone. + int i = Arrays.binarySearch(_dbmVarList, ltPair); + + if(i < 0){ + // Then the variable is in the rate zero continuous + // variables so get the range of rates from there. + + // Create an object to reference into the rate zero. + LPNContAndRate lcr = + new LPNContAndRate((LPNContinuousPair) ltPair, + new IntervalPair(0,0)); + + // Get the old version of lcr from the rate zero since + // that contains the rate. This is quite a hack. + VariableRangePair vrp = _rateZeroContinuous.get(lcr); + lcr = _rateZeroContinuous.getKey(vrp); + + return lcr.get_rateInterval(); + } + + + upper = getUpperBound(i); + lower = -1*getLowerBound(i); + + + // The continuous variable is in the Octagon. + // The upper and lower bounds are stored in the same + // place as the delays, so the same method of + // retrieval will work. + return new IntervalPair(lower, upper); + } + + /** + * Get the value of the lower bound for the delay if the index refers + * to a timer, otherwise get the lower bound for the continuous variables + * rate. + * @param index + * The timer's row/column of the DBM matrix. + * @return + * The value of the lower bound. + */ + public int getLowerBound(int index){ + return _lowerBounds[index]; + } + + /** + * Always the (negative) lower bound in warped space. + */ + @Override + public int getLowerBoundTrue(int index){ + // The matrix stores twice the lower bound. + return (int)(ContinuousUtilities.chkDiv( + _matrix[baseToPos(index)][baseToNeg(index)], + 2, + true)); + } + + /** + * Get the value of the upper bound for the delay. If the index refers + * to a timer, otherwise get the upper bound for the continuous + * variables rate. + * @param index + * The timer's row/column of the DBM matrix. + * @return + * The upper bound on the transitions delay. + */ + public int getUpperBound(int index){ + return _upperBounds[index]; + } + + /** + * Always gives the upper bound in warped space. + */ + @Override + public int getUpperBoundTrue(int index){ + // The matrix stores twice the upper bound. + return (int)(ContinuousUtilities.chkDiv( + _matrix[baseToNeg(index)][baseToPos(index)], + 2, + true)); + } + + /** + * Get the upper bound unwarped. + */ + public int getUnwarpedUpperBound(LPNContinuousPair lcpair){ + + // Get the index. + int index = Arrays.binarySearch(_dbmVarList, lcpair); + + int rate = ((LPNContinuousPair) _dbmVarList[index]) + .getCurrentRate(); + + int warpValue = getUpperBoundTrue(index); + + return warpValue * rate; + } + + /** + * Gets the rate reset value. + * @param ltPair The index for the continuous variable. + * @return The value to reset to. + */ + @Override + public int rateResetValue(LPNTransitionPair ltPair){ + + //*IntervalPair rateBounds = getRateBounds(ltPair); + IntervalPair rateBounds = getRateBounds(ltPair); + + + //*int upper = rateBounds.get_UpperBound(); + //*int lower = rateBounds.get_LowerBound(); + int lower = rateBounds.get_LowerBound(); + int upper = rateBounds.get_UpperBound(); + + + /* + * Suppose the range of rates is [a,b]. If a>=0, we set the rate to b. + * If b<=0, we set the rate to a. Otherwise, a<0 newTimers = new HashSet(); + //*HashSet oldTimers = new HashSet(); + + /* + * These sets will differentiate between the new timers and the + * old timers, that is bewteen the timers that are not already in the + * Octagon and those that are already in the Octagon. + */ + HashSet newTimers = new HashSet(); + HashSet oldTimers = new HashSet(); + + + // Copy the LPNs over. + //*newZone._lpnList = new LhpnFile[this._lpnList.length]; + //*for(int i=0; i= 0 ) + //*{ + else if (Arrays.binarySearch(this._dbmVarList, + newOct._dbmVarList[i]) >=0){ + + // The timer was already present in the zone. + //*oldTimers.add(newZone._indexToTimerPair[i]); + // The timer was already present in the Octagon. + oldTimers.add(newOct._dbmVarList[i]); + //*} + } + //*else + //*{ + else { + // The timer is a new timer. + //*newTimers.add(newZone._indexToTimerPair[i]); + newTimers.add(newOct._dbmVarList[i]); + //*} + } + //*} + } + + // Create the new matrix. + //*newZone._matrix = new int[newZone.matrixSize()][newZone.matrixSize()]; + newOct._matrix = new int[newOct.DBMsize()][newOct.DBMsize()]; + // Create the upper and lower bound + newOct._lowerBounds = new int[newOct._dbmVarList.length]; + newOct._upperBounds = new int[newOct._dbmVarList.length]; + + // Note: For simplicity, make a copy of the current Octagon and perform the + // restriction and re-canonicalization. Later add a copy re-canonicalization + // that does the steps together. + + //*Zone tempZone = this.clone(); + Octagon tempOct = this.clone(); + + //*tempZone.restrictTimer(index); + //*tempZone.recononicalize(); + tempOct.restrictTimer(index); + tempOct.recononicalize(); + + // Copy the tempZone to the new zone. + //*for(int i=0; i= 0){ + if(currentRate >=0){ + + // Copy the smallest and greatest continuous value. + //*newZone.setDbmEntryByPair(lcPair, + //* LPNTransitionPair.ZERO_TIMER_PAIR, + //* ContinuousUtilities.chkDiv(-1*values.get_LowerBound(), + //* currentRate, true)); + + //*newZone.setDbmEntryByPair(LPNTransitionPair.ZERO_TIMER_PAIR, + //* lcPair, + //* ContinuousUtilities.chkDiv(values.get_UpperBound(), + //* currentRate, true)); + + newOct._matrix[baseToPos(baseIndexPair)][baseToNeg(baseIndexPair)] + = 2*ContinuousUtilities.chkDiv(-1*values.get_LowerBound(), + currentRate, true); + + newOct._matrix[baseToNeg(baseIndexPair)][baseToPos(baseIndexPair)] + = 2*ContinuousUtilities.chkDiv(values.get_LowerBound(), + currentRate, true); + //*} + } + //*else{ + else{ + // Copy the smallest and greatest continuous value. + // For negative rates, the upper and lower bounds need + // to be switched. + //*newZone.setDbmEntryByPair(LPNTransitionPair.ZERO_TIMER_PAIR, + //* lcPair, + //* ContinuousUtilities.chkDiv(-1*values.get_LowerBound(), + //* currentRate, true)); + + //*newZone.setDbmEntryByPair(lcPair, + //* LPNTransitionPair.ZERO_TIMER_PAIR, + //* ContinuousUtilities.chkDiv(values.get_UpperBound(), + //* currentRate, true)); + + newOct._matrix[baseToNeg(baseIndexPair)][baseToPos(baseIndexPair)] + = 2*ContinuousUtilities.chkDiv(-1*values.get_LowerBound(), + currentRate, true); + + newOct._matrix[baseToPos(baseIndexPair)][baseToNeg(baseIndexPair)] + = 2*ContinuousUtilities.chkDiv(values.get_LowerBound(), + currentRate, true); + + //*} + } + //*continue; + continue; + //*} + } + + + // Get all the upper and lower bounds for the new timers. + // Get the name for the timer in the i-th column/row of DBM + //*String tranName = _lpnList[pair.get_lpnIndex()] + //* .getTransition(pair.get_transitionIndex()).getLabel(); + //*ExprTree delay = _lpnList[pair.get_lpnIndex()].getDelayTree(tranName); + String tranName = _lpnList[pair.get_lpnIndex()] + .getTransition(pair.get_transitionIndex()).getLabel(); + ExprTree delay = _lpnList[pair.get_lpnIndex()].getDelayTree(tranName); + + // Get the values of the variables for evaluating the ExprTree. + //*HashMap varValues = + //* _lpnList[pair.get_lpnIndex()] + //* .getAllVarsWithValuesAsString(localStates[pair.get_lpnIndex()] + //* .getVariableVector()); + HashMap varValues = + _lpnList[pair.get_lpnIndex()] + .getAllVarsWithValuesAsString(localStates[pair.get_lpnIndex()] + .getVariableVector()); + + if(delay == null){ + _lpnList[pair.get_lpnIndex()].changeDelay(tranName, "0"); + delay = _lpnList[pair.get_lpnIndex()].getDelayTree(tranName); + } + + // Set the upper and lower bound. + //*int upper, lower; + //*if(delay.getOp().equals("uniform")) + //*{ + int upper, lower; + if(delay.getOp().equals("uniform")){ + + + //* IntervalPair lowerRange = delay.getLeftChild() + //* .evaluateExprBound(varValues, null, null); + //* IntervalPair upperRange = delay.getRightChild() + //* .evaluateExprBound(varValues, null, null); + + IntervalPair lowerRange = delay.getLeftChild() + .evaluateExprBound(varValues, null, null); + IntervalPair upperRange = delay.getRightChild() + .evaluateExprBound(varValues, null, null); + + // The lower and upper bounds should evaluate to a single + // value. Yell if they don't. + //* if(!lowerRange.singleValue() || !upperRange.singleValue()){ + //* throw new IllegalStateException("When evaulating the delay, " + + //* "the lower or the upper bound evaluated to a range " + + //* "instead of a single value."); + //* } + if(!lowerRange.singleValue() || !upperRange.singleValue()){ + throw new IllegalStateException("When evaluating the delay, " + + "the lower or the upper bound evaluated to a range " + + "instead of a single value."); + } + + //*lower = lowerRange.get_LowerBound(); + //*upper = upperRange.get_UpperBound(); + lower = lowerRange.get_LowerBound(); + upper = upperRange.get_UpperBound(); + + } + //*} + //*else + //*{ + else{ + + + //* IntervalPair range = delay.evaluateExprBound(varValues, this, null); + + //*lower = range.get_LowerBound(); + //*upper = range.get_UpperBound(); + + IntervalPair range = delay.evaluateExprBound(varValues, this, null); + + lower = range.get_LowerBound(); + upper = range.get_UpperBound(); + + //*} + } + + + //*newZone.setLowerBoundByLPNTransitionPair(pair, lower); + //*newZone.setUpperBoundByLPNTransitionPair(pair, upper); + + int baseIndex = Arrays.binarySearch(newOct._dbmVarList, pair); + newOct._lowerBounds[baseIndex] = -1* lower; + newOct._upperBounds[baseIndex] = upper; + + //*} + } + + + //Erase relationships for continuous variables that have had new values + // assigned to them or a new non-rate zero value. + //*for(int i = 1; i(); + newOct._rateZeroContinuous = new DualHashMap(); + + // Create new _indexToTimerPair. + // First get the total number of non-zero rate continuous variables that + // are present in the old zone. + //*int totalContinuous = 0; + //*for(int i=0; i<_lpnList.length; i++){ + //*totalContinuous += _lpnList[i].getTotalNumberOfContVars(); + //*} + int totalContinuous =0; + for (int i=0; i<_lpnList.length; i++){ + totalContinuous += _lpnList[i].getTotalNumberOfContVars(); + } + + //*int numberNonZero = totalContinuous - _rateZeroContinuous.size(); + int numberNonZero = totalContinuous - _rateZeroContinuous.size(); + + + // Note: Create an object that stores the records along with this information. + //*int newNonZero = 0, newZero = 0; + //*for(UpdateContinuous record : newAssignValues.keySet()){ + //*if(record.newlyNonZero()){ + //*newNonZero++; + //*} + //*if(record.newlyZero()){ + //*newZero++; + //*} + //*} + int newNonZero = 0, newZero = 0; + for (UpdateContinuous record : newAssignValues.keySet()){ + if(record.newlyNonZero()){ + newNonZero++; + } + if(record.newlyZero()){ + newZero++; + } + } + + + //*int newSize = enabledTran.size() + numberNonZero + newNonZero - newZero + 1; + int newSize = enabledTran.size() + numberNonZero + newNonZero - newZero; + + + // Create the timer array. + //*newZone._indexToTimerPair = new LPNTransitionPair[newSize]; + newOct._dbmVarList = new LPNTransitionPair[newSize]; + + + // Add in the zero timer. + //*newZone._indexToTimerPair[0] = LPNTransitionPair.ZERO_TIMER_PAIR; + // Octagons do not have a zero timer. + + + //*int indexTimerCount = 1; + int indexTimerCount = 0; + + + // Sort the previous rate zero continuous variables into rate zero or non-zero. + //*for(LPNContAndRate ltTranPair : _rateZeroContinuous.keySet()){ + for(LPNContAndRate ltTranPair : _rateZeroContinuous.keySet()){ + + // Cast the index. + //*LPNContinuousPair ltContPair = ltTranPair.get_lcPair(); + LPNContinuousPair ltContPair = ltTranPair.get_lcPair(); + + // Check if the variable is a newly assigned value. + //*UpdateContinuous assignedLtContPair = newAssignValues.get(ltContPair); + UpdateContinuous assignedLtContPair = newAssignValues.get(ltContPair); + + + //*if(assignedLtContPair != null){ + if(assignedLtContPair != null){ + + //*if(assignedLtContPair.newlyNonZero()){ + // Variable was zero and is now non-zero, so add to the the non-zero + // references. + //*newZone._indexToTimerPair[indexTimerCount++] = + //*assignedLtContPair.get_lcrPair().get_lcPair().clone(); + //*} + if(assignedLtContPair.newlyNonZero()){ + // Variable was zero and is now non-zero, so add to the non-zero + // references. + newOct._dbmVarList[indexTimerCount++] = + assignedLtContPair.get_lcrPair().get_lcPair().clone(); + } + //*else{ + else{ + // Variable was zero and is still zero, but an assignment has been + // made. Simply add in the new assigned value. + //*VariableRangePair vrp = this._rateZeroContinuous.get(ltTranPair); + + //*newZone._rateZeroContinuous.insert(assignedLtContPair.get_lcrPair(), + //*new VariableRangePair(vrp.get_variable(), + //*assignedLtContPair.get_Value())); + VariableRangePair vrp = this._rateZeroContinuous.get(ltTranPair); + newOct._rateZeroContinuous.insert(assignedLtContPair.get_lcrPair(), + new VariableRangePair(vrp.get_variable(), + assignedLtContPair.get_Value())); + } + + //*} + } + //*} + //*else{ + //*newZone._rateZeroContinuous + //*.insert(ltTranPair, _rateZeroContinuous.get(ltTranPair)); + //*} + else{ + newOct._rateZeroContinuous + .insert(ltTranPair, _rateZeroContinuous.get(ltTranPair)); + } + + } + //*} + + + // Sort the previous non-zero variables into the rate zero and non-zero. + //*for(int i=1; this._indexToTimerPair[i] instanceof LPNContinuousPair; i++){ + for (int i=0; this._dbmVarList[i] instanceof LPNContinuousPair; i++){ + + + //*LPNContinuousPair lcPair = (LPNContinuousPair) this._indexToTimerPair[i]; + LPNContinuousPair lcPair = (LPNContinuousPair) this._dbmVarList[i]; + + // Check if an assignment has been made. + //*UpdateContinuous updateRecord = newAssignValues.get(lcPair); + UpdateContinuous updateRecord = newAssignValues.get(lcPair); + + //*if(updateRecord != null){ + if(updateRecord != null){ + + //*if(updateRecord.is_newZero()){ + if(updateRecord.is_newZero()){ + // The continuous variable is now a rate zero variable. + + //*LPNContinuousPair ltCar = updateRecord.get_lcrPair().get_lcPair(); + LPNContinuousPair ltCar = updateRecord.get_lcrPair().get_lcPair(); + + //*Variable v = _lpnList[ltCar.get_lpnIndex()]. + //*getContVar(ltCar.get_ContinuousIndex()); + Variable v = _lpnList[ltCar.get_lpnIndex()] + .getContVar(ltCar.get_ContinuousIndex()); + + // Dewarp the upper and lower bounds. + //*IntervalPair values = updateRecord.get_Value(); + //*int currentRate = getCurrentRate(ltCar); + //*values.set_LowerBound( + //*values.get_LowerBound() * currentRate); + //*values.set_UpperBound( + //*values.get_UpperBound() * currentRate); + IntervalPair values = updateRecord.get_Value(); + int currentRate = getCurrentRate(ltCar); + values.set_LowerBound( + values.get_LowerBound()*currentRate); + values.set_UpperBound( + values.get_UpperBound()*currentRate); + + // Create a VariableRangePair. + //*VariableRangePair vrp = new VariableRangePair(v, + //*values); + VariableRangePair vrp = new VariableRangePair(v, + values); + + // Add the value to the map. + //*newZone._rateZeroContinuous.insert(updateRecord.get_lcrPair(), vrp); + newOct._rateZeroContinuous.insert(updateRecord.get_lcrPair(), vrp); + } + //*} + //*else{ + else{ + // This non-zero variable still has rate non-zero, but replace + // with the newAssignValues since the rate may have changed. + //*newZone._indexToTimerPair[indexTimerCount++] = + //*updateRecord.get_lcrPair().get_lcPair(); + newOct._dbmVarList[indexTimerCount++] = + updateRecord.get_lcrPair().get_lcPair(); + } + //*} + } + //*} + //*else{ + else{ + // The variable was non-zero and hasn't had an assignment. + //*newZone._indexToTimerPair[indexTimerCount++] = + //*this._indexToTimerPair[i].clone(); + newOct._dbmVarList[indexTimerCount++] = + this._dbmVarList[i].clone(); + } + //*} + } + //*} + + + // Copy over the new transitions. + //*for(Transition t : enabledTran){ + //*int lpnIndex = t.getLpn().getLpnIndex(); + //*int tranIndex = t.getIndex(); + //*newZone._indexToTimerPair[indexTimerCount++] = + //*new LPNTransitionPair (lpnIndex, tranIndex); + //*} + for(Transition t : enabledTran){ + int lpnIndex = t.getLpn().getLpnIndex(); + int tranIndex = t.getIndex(); + newOct._dbmVarList[indexTimerCount++] = + new LPNTransitionPair (lpnIndex, tranIndex); + } + + + //*Arrays.sort(newZone._indexToTimerPair); + Arrays.sort(newOct._dbmVarList); + + } + + /** + * Restricts the lower bound of a timer. + * + * @param timer + * The timer to tighten the lower bound. + */ + private void restrictTimer(int timer) + { + //*_matrix[dbmIndexToMatrixIndex(timer)][dbmIndexToMatrixIndex(0)] + //* = getLowerBoundbydbmIndex(timer); + + _matrix[baseToPos(timer)][baseToNeg(timer)] = + 2*_lowerBounds[timer]; + } + + /** + * This method sets all the rate to their lower bound. + * Will not work quite right for continuous variables + * with rates that include zero. + */ + private void setAllToLowerBoundRate(){ + + // Loop through the continuous variables. + //*for(int i=1; i<_indexToTimerPair.length && + //* _indexToTimerPair[i] instanceof LPNContinuousPair; i++){ + //* LPNContinuousPair ltContPair = (LPNContinuousPair) _indexToTimerPair[i]; + for (int i=0; i<_dbmVarList.length && + _dbmVarList[i] instanceof LPNContinuousPair; i++){ + LPNContinuousPair ltContPair = (LPNContinuousPair) _dbmVarList[i]; + + //* For this, recall that for a continuous variable that the lower bound + //* rate is stored in the zero column of the matrix. + /* For this, recall that the lower bound rate of for a continuous + * variable is stored in the member variable _lowerBounds. + */ + + + //*int lower = -1*_matrix[dbmIndexToMatrixIndex(i)][0]; + //*int upper = _matrix[0][dbmIndexToMatrixIndex(i)]; + //*int newRate; + int lower = -1*_lowerBounds[i]; + int upper = _upperBounds[i]; + int newRate; + + /* + * Suppose the range of rates is [a,b]. If a>=0, then we set the + * rate to b. If b<=0, then we set the rate to a. Ohterwise, + * a<0=0 or lower < 0 < upper we set the + // rate to the upper bound. + //*newRate = upper; + //*} + if (upper <= 0){ + newRate = lower; + } + else { + // In both cases of lower >=0 or lower < 0 < upper we set the + // rate to the upper bound. + newRate = upper; + } + + + //*setCurrentRate(ltContPair, newRate); + setCurrentRate(ltContPair, newRate); + //*} + } + } + + public void correctNewAssignments(ContinuousRecordSet newAssignValues){ + //Erase relationships for continuous variables that have had new values + // assigned to them or a new non-rate zero value. + //*for(int i = 1; i0){ + if(lcPair.getCurrentRate() > 0){ + + + //* setDbmEntry(i, 0, + //* ContinuousUtilities.chkDiv(-1*values.get_LowerBound(), + //* currentRate, true)); + /* + * Set the lower bound. Recall in an Octagon with variable v, + * the lower bound is in v- - v+ + */ +// _matrix[baseToNeg(i)][baseToNeg(i)] = 2* +// ContinuousUtilities.chkDiv(-1*values.get_LowerBound(), +// currentRate, true); + _matrix[baseToPos(i)][baseToNeg(i)] = 2* + ContinuousUtilities.chkDiv(-1*values.get_LowerBound(), + currentRate, true); + + //* setDbmEntry(0,i, + //* ContinuousUtilities.chkDiv(values.get_UpperBound(), + //* currentRate, true)); + + /* + * Set the upper bound. Recall in an Octagon with variable v, + * the upper bound is in the entry v+ - v-. + */ + _matrix[baseToNeg(i)][baseToPos(i)] = 2* + ContinuousUtilities.chkDiv(values.get_UpperBound(), + currentRate, true); + } + //*} + //*else{ + else{ + //* setDbmEntry(i,0, + //* ContinuousUtilities.chkDiv(values.get_UpperBound(), + //* currentRate, true)); + + //* setDbmEntry(0, i, + //* ContinuousUtilities.chkDiv(-1*values.get_LowerBound(), + //* currentRate, true)); + + _matrix[baseToNeg(i)][baseToNeg(i)] = 2* + ContinuousUtilities.chkDiv(values.get_UpperBound(), + currentRate, true); + _matrix[baseToPos(i)][baseToPos(i)] = 2* + ContinuousUtilities.chkDiv(-1*values.get_LowerBound(), + currentRate, true); + + } + //*} + + // Erase the relationships. + //*for(int j=1; j(); + newOct._rateZeroContinuous = new DualHashMap(); + + //*HashSet> newlyNonZero = + //*new HashSet>(); + HashSet> newlyNonZero = + new HashSet>(); + + + //*for(Map.Entry variable : + //*_rateZeroContinuous.entrySet()){ + for(Map.Entry variable : + _rateZeroContinuous.entrySet()){ + + // Check for a single value which indicates that zero is + // the only possible rate. + //*if(variable.getValue().get_range().singleValue()){ +// if(variable.getValue().get_range().singleValue()){ + if(variable.getKey().get_rateInterval().singleValue()){ + // This variable only has zero as a rate so keep it + // in the rate zero variables. + //*newZone._rateZeroContinuous.insert(variable.getKey(), + //*variable.getValue()); + newOct._rateZeroContinuous.insert(variable.getKey(), + variable.getValue()); + } + //*} + //*else{ + else{ + // This variable will need to be added to the zone. + //*newlyNonZero.add(variable); + newlyNonZero.add(variable); + } + //*} + } + //*} + + + /* + * Calulate the size of the _indexToTimerPairs array and create + * it. + */ + /* + * Calculate the size of the _dbmVarList array and create it. + */ + + + //*int oldSize = this._indexToTimerPair.length; + //*int newSize = oldSize + newlyNonZero.size(); + int oldSize = this._dbmVarList.length; + int newSize = oldSize + newlyNonZero.size(); + + + + //*newZone._indexToTimerPair = new LPNTransitionPair[newSize]; + newOct._dbmVarList = new LPNTransitionPair[newSize]; + + /* + * Copy over the old pairs and add the new ones. + */ + //*for(int i=0; i< this._indexToTimerPair.length; i++){ + //*newZone._indexToTimerPair[i] = this._indexToTimerPair[i].clone(); + //*} + for (int i=0; i variable : + //*newlyNonZero){ + //*newZone._indexToTimerPair[oldSize++] = variable.getKey() + //*.get_lcPair().clone(); + //*} + for(Map.Entry variable : + newlyNonZero){ + newOct._dbmVarList[oldSize++] = variable.getKey() + .get_lcPair().clone(); + } + + + /* + * Sort. + */ + //*Arrays.sort(newZone._indexToTimerPair); + Arrays.sort(newOct._dbmVarList); + + /* + * Copy over the old matrix values and new constraints. + */ + //*newZone._matrix = new int[newZone.matrixSize()][newZone.matrixSize()]; + newOct._matrix = new int[newOct.DBMsize()][newOct.DBMsize()]; + newOct._lowerBounds = new int[newOct._dbmVarList.length]; + newOct._upperBounds = new int[newOct._dbmVarList.length]; + + //*for(int i =0; i< this.dbmSize(); i++){ +// for(int i=0; i variable: newlyNonZero){ + for(Map.Entry variable: newlyNonZero){ + + //*LPNTransitionPair currentVariable = variable.getKey().get_lcPair(); + LPNTransitionPair currentVariable = variable.getKey().get_lcPair(); + + //*int currentIndex = Arrays.binarySearch(newZone._indexToTimerPair, + //*currentVariable); + int currentIndex = Arrays.binarySearch(newOct._dbmVarList, + currentVariable); + + //*IntervalPair rangeOfRates = variable.getKey().get_rateInterval(); + //*IntervalPair rangeOfValues = variable.getValue().get_range(); + IntervalPair rangeOfRates = variable.getKey().get_rateInterval(); + IntervalPair rangeOfValues = variable.getValue().get_range(); + + /* + * First set the range of rates, current rate, and the lower and upper + * bounds for the newly added continuous variables. + */ + //*nnewZone.setLowerBoundbydbmIndex(currentIndex, rangeOfRates.get_LowerBound()); + //*newZone.setUpperBoundbydbmIndex(currentIndex, rangeOfRates.get_UpperBound()); + //*newZone.setDbmEntry(currentIndex, 0, -1*rangeOfValues.get_LowerBound()); + //*newZone.setDbmEntry(0, currentIndex, rangeOfValues.get_UpperBound()); + newOct._lowerBounds[currentIndex] = -1*rangeOfRates.get_LowerBound(); + newOct._upperBounds[currentIndex] = rangeOfRates.get_UpperBound(); + // The upper bound is v+ - v- and the lower bound is v- -v+ + // but remember it is column minus row. + newOct._matrix[baseToPos(currentIndex)][baseToNeg(currentIndex)] = + -2*rangeOfValues.get_LowerBound(); + newOct._matrix[baseToNeg(currentIndex)][baseToPos(currentIndex)] = + 2*rangeOfValues.get_UpperBound(); + + + //*for(int j=1; j adjustedColumns = new HashSet(); + HashSet adjustedColumns = new HashSet(); + + + //*boolean needsAdjusting = false; + boolean needsAdjusting = false; + + // Restrict the variables according to each of the inequalities in the eventSet. + //*for(Event e : eventSet){ + for (Event e: eventSet){ + // Get the inequality. + //*InequalityVariable iv = e.getInequalityVariable(); + InequalityVariable iv = e.getInequalityVariable(); + + // Extract the variable. I will assume the inequality only depends on a single + // variable. + //*Variable x = iv.getContVariables().get(0); + Variable x = iv.getContVariables().get(0); + + // Extract the index. + //*int lpnIndex = iv.get_lpn().getLpnIndex(); + int lpnIndex = iv.get_lpn().getLpnIndex(); + + // Extract the variable index. + //*DualHashMap variableIndexMap = _lpnList[lpnIndex].getContinuousIndexMap(); + //*int variableIndex = variableIndexMap.getValue(x.getName()); + DualHashMap variableIndexMap = _lpnList[lpnIndex].getContinuousIndexMap(); + int variableIndex = variableIndexMap.getValue(x.getName()); + + // Package it up for referencing. + //*LPNContinuousPair ltContPair = new LPNContinuousPair(lpnIndex, variableIndex); + LPNContinuousPair ltContPair = new LPNContinuousPair(lpnIndex, variableIndex); + + // Need the current rate for the variable, grab the stored LPNContinuousPair. + //*int zoneIndex = Arrays.binarySearch(_indexToTimerPair, ltContPair); + //*if(zoneIndex > 0){ + //*ltContPair = (LPNContinuousPair) _indexToTimerPair[zoneIndex]; + //*} + int octIndex = Arrays.binarySearch(_dbmVarList, ltContPair); + if (octIndex >= 0){ + ltContPair = (LPNContinuousPair) _dbmVarList[octIndex]; + } + + // Perform the restricting. + //*needsAdjusting = needsAdjusting | restrictContinuous(ltContPair, iv.getConstant()); + needsAdjusting = needsAdjusting | restrictContinuous(ltContPair, + iv.getConstant()); + + + //*if(needsAdjusting){ + //*adjustedColumns.add(ltContPair); + //*} + if(needsAdjusting){ + adjustedColumns.add(ltContPair); + } + + //*} + } + + // If one of the continuous variables has been moved forward, the other colmns + // need to be adjusted to keep a consistent zone. + //*if(needsAdjusting){ + if(needsAdjusting){ + + // At least one of the continuous variables has been moved forward, + // so we need to ajust the bounds to keep a consistent zone. + //*for(int i=1; i<_indexToTimerPair.length; i++){ + for (int i=0; i<_dbmVarList.length; i++){ + + //*LPNTransitionPair ltpair = _indexToTimerPair[i]; + LPNTransitionPair ltpair = _dbmVarList[i]; + + //*if(adjustedColumns.contains(ltpair)){ + if(adjustedColumns.contains(ltpair)){ + // This continuous variables already had the upper bound + // adjusted. + //*continue; + continue; + } + //*} + // Add one to the upper bounds. + //*setDbmEntry(0, i, getDbmEntry(0, i)+1); + // Adjust the upper bound to past the inequality. + // With a zone we added 1. Should we add 1 or 2 for + // Octagons? I'll choosing 1 for right now. + // Upper bound is v+ -v- (remember column minus row). + _matrix[baseToNeg(i)][baseToPos(i)] += 2; + + } + //*} + + // For every continous variable that was adjusted, need + // to adjust the b3 entry. We will add one to the b3 entry + // for each continuous variable involved. + for(int i=0; i<_dbmVarList.length; i++){ + + LPNTransitionPair ltpair = _dbmVarList[i]; +// +// if(!adjustedColumns.contains(ltpair)){ +// // If this continuous variable has not +// // had the upper bound change, then +// // do nothing. +// continue; +// } + + for (int j=0; j<_dbmVarList.length; j++){ + + if(adjustedColumns.contains(_dbmVarList[j]) && j<=i){ + continue; + } + + _matrix[baseToNeg(i)][baseToPos(j)] += 2; + _matrix[baseToNeg(j)][baseToPos(i)] += 2; + } + } + } + //*} + } + + /** + * Restricts the lower bound of a continuous variable. Also checks fixes + * the upper bound to be at least as large if needed. This method + * is usually used as a result of an event firing. + * @param ltContPair + * The index of the continuous variable to restrict. + * @param constant + * The constant value of the inequality event that is being used to update + * the variable indexed by ltContPair. + * + */ + private boolean restrictContinuous(LPNContinuousPair ltContPair, int constant){ + + // It will be quicker to get the DBM index for the ltContPair one time. + //*int variableIndex = timerIndexToDBMIndex(ltContPair); + //*int zeroIndex = timerIndexToDBMIndex(LPNTransitionPair.ZERO_TIMER_PAIR); + int baseIndex = Arrays.binarySearch(_dbmVarList, ltContPair); + + // Set the lower bound the variable (which is the DBM[variabl][0] entry. + // Note : the lower bound in the zone is actually the negative of the lower + // bound hence the -1 on the warpValue. + //*setDbmEntry(variableIndex, zeroIndex, ContinuousUtilities.chkDiv(-1*constant, ltContPair.getCurrentRate(), true)); + + // Set the lower bound for the variable (V- - v+) entry. + // Note: lower bounds are doubled in the Octagon and are negative. + int newLower = ContinuousUtilities.chkDiv(-2*constant, ltContPair.getCurrentRate(), true); + _matrix[baseToPos(baseIndex)][baseToNeg(baseIndex)] = newLower%2 == 0 ? newLower: newLower -1; + + + // Check if the upper bound needs to be advanced and advance it if necessary. + //*if(getDbmEntry(zeroIndex, variableIndex) < ContinuousUtilities.chkDiv(constant, ltContPair.getCurrentRate(), true)){ + if(_matrix[baseToNeg(baseIndex)][baseToPos(baseIndex)] + < ContinuousUtilities.chkDiv(2*constant, ltContPair.getCurrentRate(), true)){ + // If the upper bound in the zones is less than the new restricting value, we + // must advance it for the zone to remain consistent. + //*setDbmEntry(zeroIndex, variableIndex, ContinuousUtilities.chkDiv(constant, ltContPair.getCurrentRate(), true)); + + // If the upper bound in the Octagon is less than the new + // restricting value, we must advance it for the + // Octagon to remain consistent. + int newUpper = ContinuousUtilities.chkDiv(2*constant, ltContPair.getCurrentRate(), true); + _matrix[baseToNeg(baseIndex)][baseToPos(baseIndex)] = newUpper%2 == 0 ? newUpper: newUpper +1; + + + //*return true; + return true; + + //*} + } + + return false; + } + + /** + * The list of enabled timers. + * @return + * The list of all timers that have reached their lower bounds. + */ + @Override + public List getEnabledTransitions(){ + + // This method is probably not necessary and does not take + // into account continuous variables. I think the getPossibleEvents + // replaces this. + + //*ArrayList enabledTransitions = new ArrayList(); + ArrayList enabledTransitions = new ArrayList(); + + + // Check if the timer exceeds its lower bound staring with the first nonzero + // timer. + //*for(int i=1; i<_indexToTimerPair.length; i++) + //*{ + for (int i=0; i<_dbmVarList.length; i++){ + + // The upper bound is in the v+ - v- entry. A timer is able to fire + // if the upper bound is greater than or equal to the lower bound. + + //*if(getDbmEntry(0, i) >= -1 * getLowerBoundbydbmIndex(i)) + //*{ + if(_matrix[baseToNeg(i)][baseToPos(i)] >= -2*_lowerBounds[i]){ + + //*enabledTransitions.add(_lpnList[_indexToTimerPair[i].get_lpnIndex()] + //*.getTransition(_indexToTimerPair[i].get_transitionIndex())); + + enabledTransitions.add(_lpnList[_dbmVarList[i].get_lpnIndex()] + .getTransition(_dbmVarList[i].get_transitionIndex())); + //*} + } + //*} + } + + //*return enabledTransitions; + + + return enabledTransitions; + } + + /** + * Gives the list of enabled transitions associated with a particular LPN. + * @param LpnIndex + * The Index of the LPN the Transitions are a part of. + * @return + * A List of the Transitions that are enabled in the LPN given by the index. + */ + @Override + public List getEnabledTransitions(int LpnIndex){ + + // This method is probably not necessary and does not take + // into account continuous variables. The get possible events + // I think replaces this. + + //*ArrayList enabledTransitions = new ArrayList(); + ArrayList enabledTransitions = new ArrayList(); + + // Check if the timer exceeds its lower bound staring with the first nonzero + // timer. + //*for(int i=1; i<_indexToTimerPair.length; i++) + //*{ + for(int i=0; i<_dbmVarList.length; i++){ + + //*if(getDbmEntry(0, i) >= -1 * getLowerBoundbydbmIndex(i)) + //*{ + if(_matrix[baseToNeg(i)][baseToPos(i)] >= -2*_lowerBounds[i]){ + + //*LPNTransitionPair ltPair = _indexToTimerPair[i]; + LPNTransitionPair ltPair = _dbmVarList[i]; + + //*if( ltPair.get_lpnIndex() == LpnIndex){ + if(ltPair.get_lpnIndex() == LpnIndex){ + + //*enabledTransitions.add(_lpnList[ltPair.get_lpnIndex()] + //*.getTransition(ltPair.get_transitionIndex())); + + enabledTransitions.add(_lpnList[ltPair.get_lpnIndex()] + .getTransition(ltPair.get_transitionIndex())); + + //*} + } + //*} + } + //*} + } + + //*return enabledTransitions; + + return enabledTransitions; + } + + /** + * Find the next possible events. + * + * @param LpnIndex + * The index of the LPN that is of interest. + * @param localState + * The state associated with the LPN indexed by LpnIndex. + * @return + * LpnTranList is populated with a list of + * EventSets pertaining to the LPN with index LpnIndex. An EventSet can + * either contain a transition to + * fire or set of inequalities to change sign. + */ + @Override + public LpnTranList getPossibleEvents(int LpnIndex, State localState){ + + + //*LpnTranList result = new LpnTranList(); + LpnTranList result = new LpnTranList(); + + // Look through the timers and continuous variables. For the timers + // determine if they are ready to fire. For the continuous variables, + // look up the associated inequalities and see if any of them are ready + // to fire. + + + // We do not need to consider the zero timer, so start the + // for loop at i=1 and not i=0. + //*for(int i=1; i<_indexToTimerPair.length; i++){ + + for(int i=0; i<_dbmVarList.length; i++){ + + //*LPNTransitionPair ltPair = _indexToTimerPair[i]; + LPNTransitionPair ltPair = _dbmVarList[i]; + + + // The enabled events are grouped with the LPN that they affect. So if + // this pair does not belong to the current LPN under consideration, skip + // processing it. + //*if(ltPair.get_lpnIndex() != LpnIndex){ + //*continue; + //*} + if(ltPair.get_lpnIndex() != LpnIndex){ + continue; + } + + + // If the index refers to a timer (and not a continuous variable) + // and has exceeded its lower bound, then add the transition. + //*if(!(ltPair instanceof LPNContinuousPair)){ + if(!(ltPair instanceof LPNContinuousPair)){ + + + // The index refers to a timer. Now check if time has advanced + // far enough for the transition to fire. + //*if(getDbmEntry(0, i) >= -1 * getLowerBoundbydbmIndex(i)){ + + // Note the upper bound is the v+-v- entry. + if(_matrix[baseToNeg(i)][baseToPos(i)] + >= -2*_lowerBounds[i]){ + //*Event e = new Event(_lpnList[ltPair.get_lpnIndex()].getTransition(ltPair.get_transitionIndex())); + //*result = addSetItem(result, e, localState); + + Event e = new Event(_lpnList[ltPair.get_lpnIndex()] + .getTransition(ltPair.get_transitionIndex())); + result = Zone.addSetItem(this, result, e, localState); + //*} + } + //*} + } + //*else{ + else{ + + // The index refers to a continuous variable. + // First check for a rate change event. + //*LPNContinuousPair ltContPair = + //*((LPNContinuousPair) ltPair).clone(); + LPNContinuousPair ltContPair = + ((LPNContinuousPair) ltPair).clone(); + + //*IntervalPair ratePair = getRateBounds(ltContPair); + IntervalPair ratePair = getRateBounds(ltContPair); + + //*result = createRateEvents(ltContPair, ratePair, result, localState); + result = Zone.createRateEvents(this, ltContPair, ratePair, result, localState); + + + // Check all the inequalities for inclusion. + //*Variable contVar = _lpnList[ltPair.get_lpnIndex()] + //*.getContVar(ltPair.get_transitionIndex()); + Variable contVar = _lpnList[ltPair.get_lpnIndex()] + .getContVar(ltPair.get_transitionIndex()); + + + //*if(contVar.getInequalities() != null){ + if(contVar.getInequalities() != null){ + + //*for(InequalityVariable iv : contVar.getInequalities()){ + for(InequalityVariable iv : contVar.getInequalities()){ + + // Check if the inequality can change. + //*if(ContinuousUtilities.inequalityCanChange(this, iv, localState)){ + //*result = addSetItem(result, new Event(iv), localState); + //*} + + + if(ContinuousUtilities.inequalityCanChange(this, iv, localState)){ + result = Zone.addSetItem(this, result, new Event(iv), localState); + } + + //*} + } + //*} + } + } + //*} + //*} + } + + // Check the rate zero variables for possible rate change events. + //*for(LPNContAndRate lcrPair : _rateZeroContinuous.keySet()){ + for(LPNContAndRate lcrPair : _rateZeroContinuous.keySet()){ + + // Get the reference object: + //*LPNContinuousPair ltContPair = lcrPair.get_lcPair(); + LPNContinuousPair ltContPair = lcrPair.get_lcPair(); + + // Extract the range of rates. + //*IntervalPair ratePair = lcrPair.get_rateInterval(); + IntervalPair ratePair = lcrPair.get_rateInterval(); + + //*result = createRateEvents(ltContPair, ratePair, result, localState); + result = Zone.createRateEvents(this, ltContPair, ratePair, result, localState); + + //*} + } + //*return result; + //*} + return result; + } + +// private LpnTranList createRateEvents(LPNContinuousPair ltContPair, IntervalPair ratePair, +// LpnTranList result, State localState){ + + // it is probably possible to make this method static as well + // as the addSetItems method. +// return null; +// } + + /** + * Adds or removes items as appropriate to update the current + * list of possible events. Note the type LpnTranList extends + * LinkedList. The type EventSet extends transition + * specifically so that objects of EventSet type can be place in + * this list. + * @param EventList + * The list of possible events. + */ +// public LpnTranList addSetItem(LpnTranList E, Event e, State s){ + + + // It is probably not necessary to repeat this method + // unless it actually refers to the zone in the zones + // version. If that is not the case, we can make it + // a static method and use only the one. +// return null; +// } + + /** + * Warps this Octagon with the aid of rate information from the previous Octagon. + * + * @param oldOctagon + * The previous Octagon. + * @return + * The warped Octagon. + */ + public void dbmWarpOld(Octagon oldOctagon){ + + // According to atacs comments, this appears to NOT work when + // INFIN is in the bounds. + // This portion of the code handles the warping of the relative + // parts of the octagon. + //*for(int i=1; i< dbmSize(); i++){ + for(int i=1; i jVal){ + if(iVal > jVal){ + + + //*setDbmEntry(j, i, (int) + //*Math.ceil(((jWarp*getDbmEntry(j, i))/jXDot) + + //*((-1*jWarp*getDbmEntry(0, i)/jXDot)) + + //*((iWarp*getDbmEntry(0, i)/iXDot)))); + + //*setDbmEntry(i, j, (int) + //*Math.ceil(((jWarp*getDbmEntry(i, j))/jXDot) + + //*((-1*jWarp*getDbmEntry(i, 0)/jXDot)) + + //*((iWarp*getDbmEntry(i, 0)/iXDot)))); + +// _matrix[i][j] = +// Math.ceil() + + + + //*} + } + + //*else{ + else{ + //*setDbmEntry(i, j, (int) + //*Math.ceil(((iWarp*getDbmEntry(i, j))/iXDot) + + //*((-1*iWarp*getDbmEntry(0, j)/iXDot)) + + //*((jWarp*getDbmEntry(0, j)/jXDot)))); + + //*setDbmEntry(j, i, (int) + //*Math.ceil(((iWarp*getDbmEntry(j, i))/iXDot) + + //*((-1*iWarp*getDbmEntry(j, 0)/iXDot)) + + //*((jWarp*getDbmEntry(j, 0)/jXDot)))); + //*} + } + //*} + } + //*} + } + // Handle the warping of the bounds. + //*for(int i=1; i 0)){ + // Perform the swaps of the intercepts. + // b1 -> b3, b2 -> b4, b3 -> b1, b4 -> b2 + // However, the dbm stores, b1, -b2, b3, and -b4. + // So the b1 and the b3 entries are swapped directly, + // Simlarly, the -b2 and the -b4 entries are swapped + // directly. + + // Swap the bounds. +// int tmp = this._matrix[baseToNeg(i)][baseToPos(i)]; +// this._matrix[baseToNeg(i)][baseToPos(i)] = +// -1*this._matrix[baseToPos(i)][baseToNeg(i)]; +// this._matrix[baseToPos(i)][baseToNeg(i)] = -1 * tmp; +// this._matrix[baseToNeg(i)][baseToPos(i)] = +// this._matrix[baseToPos(i)][baseToNeg(i)]; +// this._matrix[baseToPos(i)][baseToNeg(i)] = tmp; + + // Save the b1 entry. + int tmp = this._matrix[baseToPos(i)][baseToPos(j)]; + + // Write over the b1 entry with b3. + this._matrix[baseToPos(i)][baseToPos(j)] = + this._matrix[baseToNeg(i)][baseToPos(j)]; + this._matrix[baseToNeg(j)][baseToNeg(i)] = + this._matrix[baseToNeg(i)][baseToPos(j)]; + + // Write over the b3 entry with b1. + this._matrix[baseToNeg(i)][baseToPos(j)] = tmp; + this._matrix[baseToNeg(j)][baseToPos(i)] = tmp; + + // Save the -b2 entry. + tmp = this._matrix[baseToNeg(i)][baseToNeg(j)]; + + // Write over the -b2 entry with -b4. + this._matrix[baseToNeg(i)][baseToNeg(j)] = + this._matrix[baseToPos(i)][baseToNeg(j)]; + this._matrix[baseToPos(j)][baseToPos(i)] = + this._matrix[baseToPos(i)][baseToNeg(j)]; + + // Write over the -b4 entry with -b2. + this._matrix[baseToPos(i)][baseToNeg(j)] = tmp; + this._matrix[baseToPos(j)][baseToNeg(i)] = tmp; + + } + else if((signx > 0) & (signy < 0)){ + // When y is negative, b1 and b4 are swapped as + // well as b2 and b3 are swapped (as well as the sign changes). + // When x is negative, b1 and b3 are swapped as well as b2 and + // b4 are swapped. + + + // Since x is positive, do not swap the bounds. +// int tmp = 0; +// int tmp = this._matrix[baseToNeg(i)][baseToPos(i)]; +// this._matrix[baseToNeg(i)][baseToPos(i)] = +// -1*this._matrix[baseToPos(i)][baseToNeg(i)]; +// this._matrix[baseToPos(i)][baseToNeg(i)] = -1 * tmp; + + // Perform the swaps of the intercepts. + // b1 -> -b4, b4 -> -b1, b3 -> -b2, b2 -> -b3 + // However, the dbm stores b1, -b2, b3, and -b4. + // So the b1 and -b4 entries are swapped directly. + // Simlarly, b3 and the -b2 entry are swapped + // directly. + // Save the b1 value. + int tmp = this._matrix[baseToPos(i)][baseToPos(j)]; + + // Write over the b1 values with -b4. + this._matrix[baseToPos(i)][baseToPos(j)] = + this._matrix[baseToPos(i)][baseToNeg(j)]; + this._matrix[baseToNeg(j)][baseToNeg(i)] = + this._matrix[baseToPos(j)][baseToNeg(i)]; + + // Write over the -b4 values with b1. + this._matrix[baseToPos(i)][baseToNeg(j)] = tmp; + this._matrix[baseToPos(j)][baseToNeg(i)] = tmp; + + // Save the b3 entry. + tmp = this._matrix[baseToNeg(i)][baseToPos(j)]; + + // Write over the b3 values with -b2. + this._matrix[baseToNeg(i)][baseToPos(j)] = + this._matrix[baseToNeg(i)][baseToNeg(j)]; + this._matrix[baseToNeg(j)][baseToPos(i)] = + this._matrix[baseToPos(j)][baseToPos(i)]; + + // Write over the -b2 values with b3. + this._matrix[baseToNeg(i)][baseToNeg(j)] = tmp; + this._matrix[baseToPos(j)][baseToPos(i)] = tmp; + } + else if((signx < 0) & (signy < 0)){ + // Perform the swaps of the intercepts. + // b1 -> -b2, b2 -> -b1, b3 -> -b4, b4 -> -b3 + // However, the dbm stores, b1, -b2, b3, and -b4. + // So the b1 and the -b2 entries are swapped directly, + // Simlarly, the b3 and the -b4 entries are swapped + // directly. + + // Swap the bounds. +// int tmp = this._matrix[baseToNeg(i)][baseToPos(i)]; +// this._matrix[baseToNeg(i)][baseToPos(i)] = +// -1*this._matrix[baseToPos(i)][baseToNeg(i)]; +// this._matrix[baseToPos(i)][baseToNeg(i)] = -1 * tmp; +// this._matrix[baseToNeg(i)][baseToPos(i)] = +// this._matrix[baseToPos(i)][baseToNeg(i)]; +// this._matrix[baseToPos(i)][baseToNeg(i)] = tmp; + + // Save the b1 entry. + int tmp = this._matrix[baseToPos(i)][baseToPos(j)]; + + // Write over the b1 entry with -b2. + this._matrix[baseToPos(i)][baseToPos(j)] = + this._matrix[baseToNeg(i)][baseToNeg(j)]; + this._matrix[baseToNeg(j)][baseToNeg(i)] = + this._matrix[baseToNeg(i)][baseToNeg(j)]; + + // Write over the -b2 entry with b1. + this._matrix[baseToNeg(i)][baseToNeg(j)] = tmp; + this._matrix[baseToPos(j)][baseToPos(i)] = tmp; + + // Save the b3 entry. + tmp = this._matrix[baseToNeg(i)][baseToPos(j)]; + + // Write over the b3 entry with -b4. + this._matrix[baseToNeg(i)][baseToPos(j)] = + this._matrix[baseToPos(i)][baseToNeg(j)]; + this._matrix[baseToNeg(i)][baseToPos(j)] = + this._matrix[baseToPos(i)][baseToNeg(j)]; + + // Write over the -b4 entry with b3. + this._matrix[baseToPos(i)][baseToNeg(j)] = tmp; + this._matrix[baseToPos(j)][baseToNeg(i)] = tmp; + } + } + } + } + + /** + * Warps this Octagon with the aid of rate information from the previous Octagon. + * + * @param oldOctagon + * The previous Octagon. + * @return + * The warped Octagon. + */ + //*public void dbmWarp(Octagon oldOctagon){ + @Override + public void dbmWarp(Equivalence oldE){ + + Octagon oldOctagon = (Octagon) oldE; + +// oldOctagon.negativeWarp(oldOctagon); + this.negativeWarp(oldOctagon); + +// for(int i=1; i= alpha or not. + //if(beta >= alpha){ + if(yold*xnew >= xold*ynew){ + // This is the warping when the 'y' is greater + // than the x. + + // Get the bounds. + + // Get the values out of the matrix. + int My =(int) Math.ceil( + this._matrix[baseToNeg(j)][baseToPos(j)]/2); + int my = (int)((-1)* + Math.ceil( + this._matrix[baseToPos(j)][baseToNeg(j)]/2)); + +// int My =(int) Math.ceil( +// oldOctagon._matrix[baseToNeg(j)][baseToPos(j)]/2); +// int my = (int)((-1)* +// Math.ceil( +// oldOctagon._matrix[baseToPos(j)][baseToNeg(j)]/2)); + + int b1 = this._matrix[baseToPos(i)][baseToPos(j)]; + int b2 = (-1)*this._matrix[baseToNeg(i)][baseToNeg(j)]; + int b3 = this._matrix[baseToNeg(i)][baseToPos(j)]; + int b4 = (-1)*this._matrix[baseToPos(i)][baseToNeg(j)]; + +// int b1new = (int) Math.ceil((beta - alpha)*My + alpha*b1); +// int negb2new = (int) Math.ceil((-1)*((beta - alpha)*my + alpha*b2)); +// int b3new = (int) Math.ceil((beta-alpha)*My + alpha*b3); +// int negb4new = (int) Math.ceil((-1)*((beta - alpha)*my + alpha*b4)); + + int b1new = (int) Math.ceil((yold/ynew - xold/xnew)*My + xold*b1/xnew); + + // The floor since b2 is a lower bound. + int b2new = (int) Math.floor((yold/ynew - xold/xnew)*my + xold*b2/xnew); + int b3new = (int) Math.ceil((yold/ynew-xold/xnew)*My + xold*b3/xnew); + + // The floor since b4 is a lower bound. + int b4new = (int) Math.floor((yold/ynew - xold/xnew)*my + xold*b4/xnew); + + + // b1 + this._matrix[baseToPos(i)][baseToPos(j)] = b1new; + + this._matrix[baseToNeg(j)][baseToNeg(i)] = b1new; + + // -b2 + this._matrix[baseToNeg(i)][baseToNeg(j)] = -1*b2new; + + this._matrix[baseToPos(j)][baseToPos(i)] = -1*b2new; + + // b3 + this._matrix[baseToNeg(i)][baseToPos(j)] = b3new; + + this._matrix[baseToNeg(j)][baseToPos(i)] = b3new; + + // -b4 + this._matrix[baseToPos(i)][baseToNeg(j)] = -1*b4new; + + this._matrix[baseToPos(j)][baseToNeg(i)] = -1*b4new; + + } + else{ + // This is the warping when the 'x' is greater + // than the y. + + // Get the bounds. + + int Mx =(int) Math.ceil( + this._matrix[baseToNeg(i)][baseToPos(i)]/2); + int mx = (int)((-1)* + Math.ceil( + this._matrix[baseToPos(i)][baseToNeg(i)]/2)); + +// int Mx =(int) Math.ceil( +// oldOctagon._matrix[baseToNeg(i)][baseToPos(i)]/2); +// int mx = (int)((-1)* +// Math.ceil( +// oldOctagon._matrix[baseToPos(i)][baseToNeg(i)]/2)); + + + int b1 = this._matrix[baseToPos(i)][baseToPos(j)]; + int b2 = (-1)*this._matrix[baseToNeg(i)][baseToNeg(j)]; + int b3 = this._matrix[baseToNeg(i)][baseToPos(j)]; + int b4 = (-1)*this._matrix[baseToPos(i)][baseToNeg(j)]; + +// int b1new = (int) Math.ceil((beta - alpha)*mx + beta*b1); +// int negb2new = (int) Math.ceil((-1)*((beta - alpha)*Mx + beta*b2)); +// int b3new = (int) Math.ceil((alpha - beta)*Mx + beta*b3); +// int negb4new = (int) Math.ceil((-1)*((alpha - beta)*mx + beta*b4)); + + int b1new = (int) Math.ceil((yold/ynew - xold/xnew)*mx + yold/ynew*b1); + + // The floor since b2 is a lower bound. + int b2new = (int) Math.floor((yold/ynew - xold/xnew)*Mx + yold/ynew*b2); + int b3new = (int) Math.ceil((xold/xnew - yold/ynew)*Mx + yold/ynew*b3); + + // The floor since b2 is a lower bound. + int b4new = (int) Math.floor((xold/xnew - yold/ynew)*mx + yold/ynew*b4); + + // b1 + this._matrix[baseToPos(i)][baseToPos(j)] = b1new; + + this._matrix[baseToNeg(j)][baseToNeg(i)] = b1new; + + // -b2 + this._matrix[baseToNeg(i)][baseToNeg(j)] = -1*b2new; + + this._matrix[baseToPos(j)][baseToPos(i)] = -1*b2new; + + // b3 + this._matrix[baseToNeg(i)][baseToPos(j)] = b3new; + + this._matrix[baseToNeg(j)][baseToPos(i)] = b3new; + + + // -b4 + this._matrix[baseToPos(i)][baseToNeg(j)] = -1*b4new; + + this._matrix[baseToPos(j)][baseToNeg(i)] = -1*b4new; + } + } + } + + // Warp the upper and lower bounds for x. + for(int i=0; i= 0){ + // The variable was found, set the rate. + //*LPNContinuousPair lcPair = (LPNContinuousPair) _indexToTimerPair[index]; + //*lcPair.setCurrentRate(currentRate); + //*} + if(index >= 0){ + // The variable was found, set the rate. + LPNContinuousPair lcPair = (LPNContinuousPair) _dbmVarList[index]; + lcPair.setCurrentRate(currentRate); + } + + } + + /** + * Adds transitions to the Octagon. + * @param newTransitions + * The newly enabled transitions. + * @return + * The resulting Octagon after adding newTransitions + */ + @Override + public Octagon addTransition(HashSet newTransitions, State[] localStates){ + + /* + * The Octagon will remain the same for all the continuous variables. + * The only thing that will change is a new transition will be added into the transitions. + */ + + // Create a Zone to alter. + //* Zone newZone = new Zone(); + // Create an Octagon to alter. + Octagon newOct = new Octagon(); + + // Create a copy of the LPN list. + //*newZone._lpnList = Arrays.copyOf(this._lpnList, this._lpnList.length); + newOct._lpnList = Arrays.copyOf(this._lpnList, this._lpnList.length); + + + // Copy the rate zero continuous variables. + //*newZone._rateZeroContinuous = this._rateZeroContinuous.clone(); + newOct._rateZeroContinuous = this._rateZeroContinuous.clone(); + + // Create a copy of the current indexing pairs. + //*newZone._indexToTimerPair = new LPNTransitionPair[_indexToTimerPair.length + newTransitions.size()]; + //*for(int i=0; i<_indexToTimerPair.length; i++){ + //*newZone._indexToTimerPair[i] = _indexToTimerPair[i]; + //*} + newOct._dbmVarList = new LPNTransitionPair[_dbmVarList.length + newTransitions.size()]; + for (int i=0; i<_dbmVarList.length; i++){ + newOct._dbmVarList[i] = _dbmVarList[i]; + } + + + // Add the new transitions to the _indexToTimerPair list. + + + //*int i = _indexToTimerPair.length; + //*for(LPNTransitionPair ltPair : newTransitions){ + //*newZone._indexToTimerPair[i++] = ltPair; + //*} + int i = _dbmVarList.length; + for (LPNTransitionPair ltPair : newTransitions){ + newOct._dbmVarList[i++] = ltPair; + } + + // Sort the _indexToTimerPair list. + //*Arrays.sort(newZone._indexToTimerPair); + Arrays.sort(newOct._dbmVarList); + + // Create matrix. + //*newZone._matrix = new int[newZone._indexToTimerPair.length+1][newZone._indexToTimerPair.length+1]; + newOct._matrix = new int[newOct.DBMsize()][newOct.DBMsize()]; + + // Create the upper and lower bound arrays. + // Add the creation of the upper and lower bound arrays. Done + newOct._lowerBounds = new int[newOct._dbmVarList.length]; + newOct._upperBounds = new int[newOct._dbmVarList.length]; + + + // Convert the current transitions to a collection of transitions. + //*HashSet oldTransitionSet = new HashSet(); + //*for(LPNTransitionPair ltPair : _indexToTimerPair){ + //*oldTransitionSet.add(ltPair); + //*} + HashSet oldTransitionSet = new HashSet(); + for(LPNTransitionPair ltPair : _dbmVarList){ + oldTransitionSet.add(ltPair); + } + + // Copy in the new transitions. + //*newZone.copyTransitions(this, newTransitions, oldTransitionSet, localStates); + newOct.copyTransitions(this, newTransitions, oldTransitionSet, localStates); + + //return newZone; + //} + + return newOct; + } + + /** + * Copies in the new values needed to add a set of new times. + * @param newZone + * The zone that the values are going to be copied into. + * @param tempZone + * The zone to look up current values of timers. + * @param newTimers + * A collection of the new timers. + * @param oldTimers + * A collection of the older timers. + * @param localStates + * The current state. + */ + private void copyTransitions(Octagon tmpOct, Collection newTimers, + Collection oldTimers, State[] localStates){ + + + // Copy the tempZone to the new zone. + //*for(int i=0; i varValues = + //*_lpnList[pair.get_lpnIndex()] + //*.getAllVarsWithValuesAsString(localStates[pair.get_lpnIndex()].getVariableVector()); + HashMap varValues = + _lpnList[pair.get_lpnIndex()] + .getAllVarsWithValuesAsString(localStates[pair.get_lpnIndex()] + .getVariableVector()); + + + // Set the upper and lower bound. + //*int upper, lower; + //*if(delay.getOp().equals("uniform")) + //*{ + int upper, lower; + if (delay.getOp().equals("uniform")){ + + //*IntervalPair lowerRange = delay.getLeftChild() + //*.evaluateExprBound(varValues, null, null); + //*IntervalPair upperRange = delay.getRightChild() + //*.evaluateExprBound(varValues, null, null); + IntervalPair lowerRange = delay.getLeftChild() + .evaluateExprBound(varValues, null, null); + IntervalPair upperRange = delay.getRightChild() + .evaluateExprBound(varValues, null, null); + + + // The lower and upper bounds should evaluate to a single + // value. Yell if they don't. + //*if(!lowerRange.singleValue() || !upperRange.singleValue()){ + //*throw new IllegalStateException("When evaulating the delay, " + + //*"the lower or the upper bound evaluated to a range " + + //*"instead of a single value."); + //*} + if(!lowerRange.singleValue() || !upperRange.singleValue()){ + throw new IllegalStateException("When evaluation the delay, " + + " the lower or the upper bound evaluated to a range" + + " instead of a single value."); + } + + //*lower = lowerRange.get_LowerBound(); + //*upper = upperRange.get_UpperBound(); + lower = lowerRange.get_LowerBound(); + upper = upperRange.get_UpperBound(); + } + //*} + //*else + //*{ + else{ + //*IntervalPair range = delay.evaluateExprBound(varValues, this, null); + IntervalPair range = delay.evaluateExprBound(varValues, this, null); + + + //*lower = range.get_LowerBound(); + //*upper = range.get_UpperBound(); + + lower = range.get_LowerBound(); + upper = range.get_UpperBound(); + //*} + } + + //*setLowerBoundByLPNTransitionPair(pair, lower); + //*setUpperBoundByLPNTransitionPair(pair, upper); + + int base = Arrays.binarySearch(_dbmVarList, pair); + _lowerBounds[base] = -1*lower; + _upperBounds[base] = upper; + } + //*} + } + + /** + * This method moves a rate-zero variable into the DBM Octagon portion. + * The purpose of this method is to handle when a rate-zero variable + * is assigned a non-zero rate. + * @param ltContPair The continuous variable to move from the rate zero + * variables. + * @return The resulting Octagon. + */ + @Override + public Octagon moveOldRateZero(LPNContinuousPair ltContPair) { + + // Create a Zone to alter. + //*Zone newZone = new Zone(); + // Create an Octagon to alter. + Octagon newOct = new Octagon(); + + + // Create a copy of the LPN list. + //*newZone._lpnList = Arrays.copyOf(this._lpnList, this._lpnList.length); + newOct._lpnList = Arrays.copyOf(this._lpnList, this._lpnList.length); + + // Copy the rate zero continuous variables. + //*newZone._rateZeroContinuous = this._rateZeroContinuous.clone(); + newOct._rateZeroContinuous = this._rateZeroContinuous.clone(); + + // Extract the continuous variable from the rate zero variables. + //*LPNContAndRate rateZero = new LPNContAndRate(ltContPair, + //*new IntervalPair(0,0)); + LPNContAndRate rateZero = new LPNContAndRate(ltContPair, + new IntervalPair(0,0)); + + // This gets the values for the continuous variable. + //*VariableRangePair vrp = newZone._rateZeroContinuous.get(rateZero); + //*IntervalPair values = vrp.get_range(); + VariableRangePair vrp = newOct._rateZeroContinuous.get(rateZero); + IntervalPair values = vrp.get_range(); + + + // This replaces the rateZero with the one stored in the _rateZeroContinuous. + // The purpose of this is to obtain the stored range of rates. + //*rateZero = newZone._rateZeroContinuous.getKey(vrp); + rateZero = newOct._rateZeroContinuous.getKey(vrp); + + + // Get the range of rates. + //*IntervalPair rangeOfRates = rateZero.get_rateInterval(); + IntervalPair rangeOfRates = rateZero.get_rateInterval(); + + + // Remove the continuous variable. + //*newZone._rateZeroContinuous.delete(rateZero); + newOct._rateZeroContinuous.delete(rateZero); + + // Create a copy of the current indexing pairs. + //*newZone._indexToTimerPair = new LPNTransitionPair[_indexToTimerPair.length + 1]; + //*for(int i=0; i<_indexToTimerPair.length; i++){ + //*newZone._indexToTimerPair[i] = _indexToTimerPair[i]; + //*} + newOct._dbmVarList = new LPNTransitionPair[_dbmVarList.length + 1]; + for(int i=0; i<_dbmVarList.length; i++){ + newOct._dbmVarList[i] = _dbmVarList[i]; + } + + + // Add the continuous variable to the list of variables/transition in the DBM. + //*int numOfTransitions = _indexToTimerPair.length; + //*newZone._indexToTimerPair[numOfTransitions] = ltContPair; + int numOfTransitions = _dbmVarList.length; + newOct._dbmVarList[numOfTransitions] = ltContPair; + + // Sort the _indexToTimerPair list. + //*Arrays.sort(newZone._indexToTimerPair); + Arrays.sort(newOct._dbmVarList); + + // Create matrix. + //*newZone._matrix = new int[newZone._indexToTimerPair.length+1][newZone._indexToTimerPair.length+1]; +// newOct._matrix = new int[newOct._dbmVarList.length][newOct._dbmVarList.length]; + newOct._matrix = new int[newOct.DBMsize()][newOct.DBMsize()]; + + // Convert the current transitions to a collection of transitions. + //*HashSet oldTransitionSet = new HashSet(); + //*for(LPNTransitionPair ltPair : _indexToTimerPair){ + //*oldTransitionSet.add(ltPair); + //*} + HashSet oldTransitionSet = new HashSet(); + for(LPNTransitionPair ltPair : _dbmVarList){ + oldTransitionSet.add(ltPair); + } + + + // Copy in the new transitions. + //*newZone.copyTransitions(this, new HashSet(), + //*oldTransitionSet, null); + newOct.copyTransitions(this, new HashSet(), + oldTransitionSet, null); + + + // Get the index for the variable. + //*int index = Arrays.binarySearch(newZone._indexToTimerPair, ltContPair); + int index = Arrays.binarySearch(newOct._dbmVarList, ltContPair); + + // Copy in the range of rates. + //*newZone.setLowerBoundbydbmIndex(index, rangeOfRates.get_LowerBound()); + //*newZone.setUpperBoundbydbmIndex(index, rangeOfRates.get_UpperBound()); + newOct._lowerBounds[index] = -1*rangeOfRates.get_LowerBound(); + newOct._upperBounds[index] = rangeOfRates.get_UpperBound(); + + + //*if(ltContPair.getCurrentRate()>0){ + if(ltContPair.getCurrentRate()>0){ + + // Set the upper and lower bounds. + //*newZone.setDbmEntry(0, index, + //*ContinuousUtilities.chkDiv(values.get_UpperBound(), + //*ltContPair.getCurrentRate(), true)); + //*newZone.setDbmEntry(index, 0, + //*ContinuousUtilities.chkDiv(-1*values.get_LowerBound(), + //*ltContPair.getCurrentRate(), true)); + newOct._matrix[baseToNeg(index)][baseToPos(index)] = + 2*ContinuousUtilities.chkDiv(values.get_UpperBound(), + ltContPair.getCurrentRate(), true); + newOct._matrix[baseToPos(index)][baseToNeg(index)] = + 2*ContinuousUtilities.chkDiv(-1*values.get_LowerBound(), + ltContPair.getCurrentRate(), true); + } + //*} + //*else{ + else{ + // Set the upper and lower bounds. Since the rate is zero + // We swap the real upper and lower bounds. + //*newZone.setDbmEntry(0, index, + //*ContinuousUtilities.chkDiv(values.get_LowerBound(), + //*ltContPair.getCurrentRate(), true)); + //*newZone.setDbmEntry(index, 0, + //*ContinuousUtilities.chkDiv(-1*values.get_UpperBound(), + //*ltContPair.getCurrentRate(), true)); + + newOct._matrix[baseToNeg(index)][baseToPos(index)] = + 2*ContinuousUtilities.chkDiv(values.get_LowerBound(), + ltContPair.getCurrentRate(), true); + newOct._matrix[baseToPos(index)][baseToNeg(index)] = + 2*ContinuousUtilities.chkDiv(-1*values.get_UpperBound(), + ltContPair.getCurrentRate(), true); + } + //*} + + // Set the DBM to having no relating information for how this + // variables relates to the other variables. + //*for(int i=1; i 9) + { + result += "\n"; + count = 0; + } + } + + if(!_rateZeroContinuous.isEmpty()){ + result += "\nRate Zero Continuous : \n"; + for (LPNContAndRate lcrPair : _rateZeroContinuous.keySet()){ + result += "" + _rateZeroContinuous.get(lcrPair) + + "Rate: " + lcrPair.get_rateInterval(); + } + } + + result += "\nDBM\n"; + + + // Print the DBM. + for(int i=0; i<2*_dbmVarList.length; i++) + { +// result += "| " + String.format("%3d", getDbmEntry(i, 0)); + result += "| " + String.format("%3d", _matrix[i][0]); + + for(int j=1; j<2*_dbmVarList.length; j++) + { + +// result += ", " + String.format("%3d",getDbmEntry(i, j)); + result += ", " + String.format("%3d",_matrix[i][j]); + } + + result += " |\n"; + } + + + return result; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/Analysis_Timed.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/Analysis_Timed.java new file mode 100644 index 000000000..30aefb950 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/Analysis_Timed.java @@ -0,0 +1,382 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zone; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Stack; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.logicAnalysis.Analysis; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LPNTranRelation; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LpnTranList; +import edu.utah.ece.async.lema.verification.platu.project.PrjState; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zone.TimedState; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zone.ZoneType; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Analysis_Timed extends Analysis{ + + public Analysis_Timed(StateGraph[] lpnList, State[] initStateArray, + LPNTranRelation lpnTranRelation, String method) { + super(lpnList, initStateArray, lpnTranRelation, method); + } + + public Analysis_Timed(StateGraph[] lpnList) { + super(lpnList); + } + + int iterations = 0; + int stack_depth = 0; + int max_stack_depth = 0; + + //public StateGraph_timed[] search_dfs_timed(final StateGraph_timed[] sgList, + // final TimedState[] initStateArray) { + public StateGraph_timed[] search_dfs_timed(final StateGraph_timed[] sgList, + final State[] initStateArray){ + System.out.println("---> calling function search_dfs_timed"); + + double peakUsedMem = 0; + double peakTotalMem = 0; + boolean failure = false; + int tranFiringCnt = 0; + int totalStates = 1; + int arraySize = sgList.length; + + //Stack stateStack = new Stack(); + HashSet stateStack = new HashSet(); + Stack> lpnTranStack = new Stack>(); + Stack curIndexStack = new Stack(); + + HashSet prjStateSet = new HashSet(); + + PrjState initPrjState = new PrjState(initStateArray); + prjStateSet.add(initPrjState); + //initPrjState.print(getLpnList(sgList)); + + PrjState stateStackTop = initPrjState; + stateStack.add(stateStackTop); + + constructDstLpnList(sgList); + printDstLpnList(sgList); + + LpnTranList initEnabled = sgList[0].getEnabled(initStateArray[0]); + lpnTranStack.push(initEnabled.clone()); + curIndexStack.push(0); + + main_while_loop: while (failure == false && stateStack.size() != 0) { + + long curTotalMem = Runtime.getRuntime().totalMemory(); + long curUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + + if (curTotalMem > peakTotalMem) + peakTotalMem = curTotalMem; + + if (curUsedMem > peakUsedMem) + peakUsedMem = curUsedMem; + + if (stateStack.size() > max_stack_depth) + max_stack_depth = stateStack.size(); + + iterations++; + if (iterations % 100000 == 0) { + System.out.println("---> #iteration " + iterations + + "> # LPN transition firings: " + tranFiringCnt + + ", # of prjStates found: " + totalStates + + ", stack_depth: " + stateStack.size() + + " used memory: " + (float) curUsedMem / 1000000 + + " free memory: " + + (float) Runtime.getRuntime().freeMemory() / 1000000); + } + + State[] curStateArray = stateStackTop.toStateArray(); //stateStack.peek(); + int curIndex = curIndexStack.peek(); + LinkedList curEnabled = lpnTranStack.peek(); + + // If all enabled transitions of the current LPN are considered, + // then consider the next LPN + // by increasing the curIndex. + // Otherwise, if all enabled transitions of all LPNs are considered, + // then pop the stacks. + if (curEnabled.size() == 0) { + lpnTranStack.pop(); + curIndexStack.pop(); + curIndex++; + while (curIndex < arraySize) { + curEnabled = (sgList[curIndex].getEnabled(curStateArray[curIndex])).clone(); + if (curEnabled.size() > 0) { + lpnTranStack.push(curEnabled); + curIndexStack.push(curIndex); + break; + } + curIndex++; + } + } + if (curIndex == arraySize) { + prjStateSet.add(stateStackTop); + stateStack.remove(stateStackTop); + stateStackTop = stateStackTop.getFather(); + continue; + } + + Transition firedTran = curEnabled.removeLast(); +// System.out.println("###################"); +// System.out.println("Fired transition: " + firedTran.getName()); + //TimedState[] nextStateArray = + State[] nextStateArray = + //sgList[curIndex].fire(sgList, (TimedState[]) curStateArray, firedTran); + sgList[curIndex].fire(sgList, curStateArray, firedTran); + tranFiringCnt++; + + // Check if the firedTran causes disabling error or deadlock. + @SuppressWarnings("unchecked") + LinkedList[] curEnabledArray = new LinkedList[arraySize]; + @SuppressWarnings("unchecked") + LinkedList[] nextEnabledArray = new LinkedList[arraySize]; + for (int i = 0; i < arraySize; i++) { + StateGraph_timed sg = sgList[i]; + LinkedList enabledList = sg.getEnabled(curStateArray[i]); + curEnabledArray[i] = enabledList; + enabledList = sg.getEnabled(nextStateArray[i]); + //enabledList = sg.getEnabled(nextStateArray[i]); + nextEnabledArray[i] = enabledList; + Transition disabledTran = firedTran.disablingError( + curEnabledArray[i], nextEnabledArray[i]); + if (disabledTran != null) { + System.err.println("Disabling Error: " + + disabledTran.getFullLabel() + " is disabled by " + + firedTran.getFullLabel()); + failure = true; + break main_while_loop; + } + } + + if (Analysis.deadLock(sgList, nextStateArray) == true) { + System.out.println("*** Verification failed: deadlock."); + failure = true; + break main_while_loop; + } + + PrjState nextPrjState = new PrjState(nextStateArray); + //nextPrjState.print(getLpnList(sgList)); + //Boolean existingState = prjStateSet.contains(nextPrjState) || stateStack.contains(nextPrjState); + + Boolean existingState = checkStateSet(prjStateSet, nextPrjState, + ZoneType.getSubsetFlag(), ZoneType.getSupersetFlag()) + | checkStack(nextPrjState, stateStackTop, lpnTranStack, + curIndexStack, stateStack, ZoneType.getSubsetFlag(), + ZoneType.getSupersetFlag()); + + + if (existingState == false) { + //prjStateSet.add(nextPrjState); + stateStackTop.setChild(nextPrjState); + nextPrjState.setFather(stateStackTop); + stateStackTop = nextPrjState; + stateStack.add(stateStackTop); + lpnTranStack.push((LpnTranList) nextEnabledArray[0].clone()); + curIndexStack.push(0); + totalStates++; + } + } + + double totalStateCnt = prjStateSet.size(); + + System.out.println("---> final numbers: # LPN transition firings: " + tranFiringCnt + + ", # of prjStates found: " + totalStateCnt + + ", max_stack_depth: " + max_stack_depth + + ", peak total memory: " + peakTotalMem / 1000000 + " MB" + + ", peak used memory: " + peakUsedMem / 1000000 + " MB"); + + return sgList; + } + + private static void constructDstLpnList(StateGraph[] lpnList) { + for (int i=0; i> lpnTranStack, Stack curIndexStack, + HashSet stateStack, boolean subsets, + boolean supersets){ + + boolean existingState = false; + + if(!subsets && !supersets){ + return stateStack.contains(nextPrjState); + } + + ZoneType nextZone = ((TimedState) nextPrjState.get(0)).getZone(); + + PrjState stackStateIterator = stateStackTop; + int stackDepth = 1; + while(stackStateIterator != null){ + + if(!projectUntimedEquals(nextPrjState, stackStateIterator)){ + stackStateIterator = stackStateIterator.getFather(); + stackDepth++; + continue; + } + + ZoneType iteratorZone = ((TimedState) stackStateIterator.get(0)).getZone(); + + // Check for subset. + if(subsets && nextZone.subset(iteratorZone) + || (nextZone.equals(iteratorZone))){ + +// if(supersets){ +// existingState |= true; +// } +// else{ + existingState = true; + break; + //} + } + + if(!supersets){ + stackStateIterator = stackStateIterator.getFather(); + stackDepth++; + continue; + } + + // Check for the superset. + if(iteratorZone.subset(nextZone)){ + PrjState father = stackStateIterator.getFather(); + PrjState child = stackStateIterator.getChild(); + + if(child != null){ + child.setFather(father); + } + if(father != null){ + father.setChild(child); + } + + + // Remove the corresponding items on the stacks and state set. + lpnTranStack.remove(lpnTranStack.size() - stackDepth); + curIndexStack.remove(curIndexStack.size() - stackDepth); + stateStack.remove(stackStateIterator); + + stackStateIterator = stackStateIterator.getFather(); + continue; + } + + stackStateIterator = stackStateIterator.getFather(); + stackDepth++; + } + + + return existingState; + } + + private static boolean checkStateSet(HashSet prjStateSet, PrjState nextPrjState, + boolean subsets, boolean supersets){ + + if(!subsets && !supersets){ + return prjStateSet.contains(nextPrjState); + } + + // Extract the zone. + ZoneType nextZone = ((TimedState) nextPrjState.get(0)).getZone(); + + Iterator stateSetIterator = prjStateSet.iterator(); + while(stateSetIterator.hasNext()){ + + PrjState nextSetState = stateSetIterator.next(); + + if(!projectUntimedEquals(nextPrjState, nextSetState)){ + continue; + } + + // Check for the subsets. + ZoneType iteratorZone = ((TimedState) nextSetState.get(0)).getZone(); + + if(subsets){ + //stateSetIterator.remove(); + //if(supersets && nextZone != iteratorZone){ + if(supersets){ + if(nextZone.subset(iteratorZone)){ + return true; + } + else if(iteratorZone.subset(nextZone)){ + stateSetIterator.remove(); + } + } + else if (nextZone.subset(iteratorZone)){ + //return nextZone.subset(iteratorZone); + return true; + } + } + else if (nextZone.equals(iteratorZone)){ + //return nextZone.equals(iteratorZone); + return true; + } + } + + return false; + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/Project_Timed.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/Project_Timed.java new file mode 100644 index 000000000..c4875a8f2 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/Project_Timed.java @@ -0,0 +1,215 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zone; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.platu.logicAnalysis.Analysis; +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.project.Project; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zone.TimedState; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Project_Timed extends Project{ + + /* The list for timing analysis */ + protected List designUnitTimedSet; + private boolean _useGraph; + + public Project_Timed() { + super(); + } + + public Project_Timed(ArrayList lpns) { + super(lpns); + } + + /** + * If the OptionsFlag is false, then this constructor is identical to + * Poject(LhpnFile lpn). If the OptionsFlag is true, this constructor uses + * StateGraph_timed objects. + * + * @author Andrew N. Fisher + * + * @param lpn + * The lpn under consideration. + * @param OptionsFlag + * True for timing analysis and false otherwise. The option should match + * Options.getTimingAnalysisFlag(). + */ + public Project_Timed(LPN lpn, boolean OptionsFlag, boolean usegraph) + { + _useGraph = usegraph; + + if(Options.getTimingAnalysisFlag()) + { + this.label = ""; + this.designUnitSet = new ArrayList(0); + this.designUnitTimedSet = new ArrayList(1); + StateGraph_timed stategraph = new StateGraph_timed(lpn); + designUnitTimedSet.add(stategraph); + } + else + { + this.label = ""; + this.designUnitSet = new ArrayList(1); + StateGraph stateGraph = new StateGraph(lpn); + designUnitSet.add(stateGraph); + } + } + + public Project_Timed(LPN lpn) { + super(lpn); + } + + @Override + public void search() { + validateInputs(); + +// if(Options.getSearchType().equals("compositional")){ +// this.analysis = new CompositionalAnalysis(); +// +// if(Options.getParallelFlag()){ +// this.analysis.parallelCompositionalFindSG(this.designUnitSet); +// } +// else{ +// this.analysis.findReducedSG(this.designUnitSet); +// } +// +// return; +// } + + long start = System.currentTimeMillis(); + int lpnCnt = designUnitTimedSet.size(); + + /* Prepare search by placing LPNs in an array in the order of their indices.*/ + StateGraph_timed[] sgArray = new StateGraph_timed[lpnCnt]; + int idx = 0; +// for (StateGraph du : designUnitSet) { +// LhpnFile lpn = du.getLpn(); +// lpn.setIndex(idx++); +// sgArray[lpn.getIndex()] = du; +// } + + // If timing, then create the sgArray with StateGraph_timed objects. + if(Options.getTimingAnalysisFlag()) + { + for(StateGraph_timed du : this.designUnitTimedSet) + { + LPN lpn = du.getLpn(); + lpn.setLpnIndex(idx++); + sgArray[lpn.getLpnIndex()] = du; + } + } + + // Initialize the project state + HashMap varValMap = new HashMap(); + //TimedState[] initStateArray = new TimedState[lpnCnt]; + State[] initStateArray = new State[lpnCnt]; + + for (int index = 0; index < lpnCnt; index++) { + LPN curLpn = sgArray[index].getLpn(); + StateGraph_timed curSg = sgArray[index]; + + // TODO: Does this method need to be different than getInitState() + initStateArray[index] = curSg.getInitStateTimed(_useGraph); //curLpn.getInitState(); + int[] curStateVector = initStateArray[index].getVariableVector(); + varValMap = curLpn.getAllVarsWithValuesAsInt(curStateVector); +// HashMap vars = curLpn.getAllOutputs();//curLpn.getAllOutputs(); +// DualHashMap VarIndexMap = curLpn.getVarIndexMap(); +// for(String var : vars.keySet()) { +// varValMap.put(var, curStateVector[VarIndexMap.getValue(var)]); +// } + + } + + // TODO: (future) Need to adjust the transition vector as well? + // Adjust the value of the input variables in LPN in the initial state. + // Add the initial states into their respective LPN. + for (int index = 0; index < lpnCnt; index++) { + StateGraph_timed curSg = sgArray[index]; + initStateArray[index].update(curSg, varValMap, curSg.getLpn().getVarIndexMap()); + //initStateArray[index] = (TimedState)curSg.addState(initStateArray[index]); + curSg.addState(((TimedState) initStateArray[index]).getState()); + } + + // Initialize the zones for the initStateArray, if timing is enabled. + if(Options.getTimingAnalysisFlag()) + { + for(int index =0; index < lpnCnt; index++) + { + if(sgArray[index] != null) + { + + } + } + } + +// if (Options.getTimingAnalysisFlag()) { +// new TimingAnalysis(sgArray); +// return; +// } +// else if(!Options.getTimingAnalysisFlag()) { +// Analysis tmp = new Analysis(sgArray, initStateArray, lpnTranRelation, Options.getSearchType()); +// // Analysis tmp = new Analysis(lpnList, curStateArray, +// // lpnTranRelation, "dfs_por"); +// //Analysis tmp = new Analysis(modArray, initStateArray, lpnTranRelation, "dfs"); +// //Analysis tmp = new Analysis(modArray, initStateArray, lpnTranRelation, "dfs_noDisabling"); +// } +// else { +// System.out.println("---> Error: wrong value for option 'timingAnalysis'"); +// return; +// } + + /* Entry point for the timed analysis. */ + if(Options.getTimingAnalysisFlag()) + { + Analysis_Timed dfsTimedStateExploration = new Analysis_Timed(sgArray); + long startTimed = System.currentTimeMillis(); + // TODO: states not used + //StateGraph_timed[] states = dfsTimedStateExploration.search_dfs_timed(sgArray, initStateArray); + dfsTimedStateExploration.search_dfs_timed(sgArray, initStateArray); + long elapsedTimeMillisForTimed = System.currentTimeMillis() - startTimed; + System.out.println("---> totoal runtime: " + (double)elapsedTimeMillisForTimed/1000 + " sec\n"); + //return new StateGraph_timed[0]; + + } + + Analysis dfsStateExploration = new Analysis(sgArray); + //StateGraph[] stateGraphArray = dfsStateExploration.search_dfs(sgArray, initStateArray); + dfsStateExploration.search_dfs(sgArray, initStateArray); + + long elapsedTimeMillis = System.currentTimeMillis() - start; + float elapsedTimeSec = elapsedTimeMillis/1000F; + + System.out.println("---> total runtime: " + elapsedTimeSec + " sec\n"); + + //return stateGraphArray; + + //return new StateGraph_timed[0]; + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/StateGraph_timed.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/StateGraph_timed.java new file mode 100644 index 000000000..326e542d0 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/StateGraph_timed.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zone; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.util.HashMap; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LpnTranList; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zone.TimedState; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zone.ZoneType; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class StateGraph_timed extends StateGraph{ + + public StateGraph_timed(LPN lpn) { + super(lpn); + } + + + +// public LpnTranList getEnabled(TimedState curState) + @Override + public LpnTranList getEnabled(State curState) + { + // TODO: Overrides the base state and must add checks with zones. + // Note : Can also just make a new method signature with the TimedState + +// LpnTranList initEnabled = super.getEnabled(curState); +// +// List enabledByZone = curState.getEnabledTransitionByZone(); +// +// for(Transition T : enabledByZone) +// { +// initEnabled.remove(T); +// } +// +// return initEnabled; + + return new LpnTranList(((TimedState) curState).getEnabledTransitionByZone()); + } + + //public TimedState[] fire(final StateGraph_timed[] curSgArray, + // final State[] curStateArray, Transition firedTran) + public State[] fire(final StateGraph_timed[] curSgArray, + final State[] curStateArray, Transition firedTran) + { + // TODO: Overrides the base and must add the zone factor. + + State[] newState = super.fire(curSgArray, curStateArray, firedTran); + //TimedState[] newTimedStates = new TimedState[newState.length]; + State[] newTimedStates = new State[newState.length]; + + for(int i=0; i stateTransitionPair = nextStateMap.get(curState); + for (Transition curTran : stateTransitionPair.keySet()) { + String curStateName = "S" + curState.getIndex(); + String nextStateName = "S" + stateTransitionPair.get(curTran).getIndex(); + String curTranName = curTran.getLabel(); + out.write(curStateName + " -> " + nextStateName + " [label=\"" + curTranName + "\"]\n"); + } + } + out.write("}"); + out.close(); + } + catch (Exception e) { + e.printStackTrace(); + System.err.println("Error outputting state graph as dot file."); + } + + } + + +// public TimedState addState(State mState) +// { +// return null; +// } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/TestZoneFiles.txt b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/TestZoneFiles.txt new file mode 100644 index 000000000..3191fb8dd --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/TestZoneFiles.txt @@ -0,0 +1,40 @@ +// This file contains zones for testing. +// The format has start to indicate the beginning of a zone definition. +// The next line has the activated timers. This is a string of positive +// integers separated by spaces. A '#' sign indicates no timers are enabled. +// The next lines describe the matrix. One line per row and each row +// is a string of integers separated by spaces. +// The word 'end' is used to indicate the end of the definition. +// Lines starting with '//' are comments and anything between +// the words 'start' and 'end' will be ignored. +// Example +// +// start +// 3 5 +// 0 0 3 4 +// 0 0 2 2 +// -1 0 0 0 +// -2 0 0 0 +// end +// +// Describes a zone with two timers 3 and 5. The delay of 3 is [1, 3] and the delay for 5 +// is [2, 4]. The DBM is +// 0 2 2 +// 0 0 0 +// 0 0 0. +// +// Example +// # +// start +// +// 0 0 +// 0 0 +// end +// +// Describes a zone with only the zeroth timer. + +start +# +0 0 +0 0 +end \ No newline at end of file diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/TimedPrjState.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/TimedPrjState.java new file mode 100644 index 000000000..0e67a5d07 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/TimedPrjState.java @@ -0,0 +1,195 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zone; + +import java.util.Arrays; + +import edu.utah.ece.async.lema.verification.platu.platuLpn.LpnTranList; +import edu.utah.ece.async.lema.verification.platu.project.PrjState; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class TimedPrjState extends PrjState{ + protected ZoneType[] _zones; + + public TimedPrjState(final State[] other, final ZoneType[] otherZones){ + super(other); + this._zones = otherZones; + } + + public TimedPrjState(State[] initStateArray) { + super(initStateArray); + _zones = new Zone[initStateArray.length]; + for(int i=0; i<_zones.length; i++){ + _zones[i] = new Zone(initStateArray[i]); + } + } + + + public ZoneType[] toZoneArray(){ + return _zones; + } + + @Override + public boolean equals(Object other){ + if(!super.equals(other)){ + return false; + } + + if(!(other instanceof TimedPrjState)){ + return false; + } + + TimedPrjState otherTimedPrjState = (TimedPrjState) other; + + if(this._zones == otherTimedPrjState._zones){ + return true; + } + + if(!Arrays.equals(this._zones, otherTimedPrjState._zones)){ + return false; + } + + return true; + } + + @Override + public String toString(){ + String result = super.toString(); + + result += "\nZones: \n"; + + for(ZoneType z : _zones){ + result += z.toString() + "\n"; + } + + return result; + } + + public LpnTranList getEnabled(int zoneNumber){ + + // ZoneType to consider + ZoneType z = _zones[zoneNumber]; + + return new LpnTranList(z.getEnabledTransitions()); + } + + /** + * Gets a project state containing the un-timed portion of this timed project state. + * @return + * A project state that has the same set of (local) un-timed states. + */ + public PrjState getUntimedPrjState(){ + return new PrjState(toStateArray()); + } + + /** + * Checks if all the zones are subsets (or equal to) the corresponding other zones as well + * as if the un-timed portions are equal. Note: it is assumed that both states have the same + * number of zones. + * @param other + * The state to compare against. + * @return + * True if zone zi is a subset of zone z'i for all i where zi is the i-th zone + * of this TimedPrjState and z'i is the i-th zone of the other TimedPrjState and + * the un-timed portion of the states are equal. + */ + public boolean subset(TimedPrjState other){ + // For clarity, extract the un-timed portions. Alternately, super.equals(otherState) would + // probably work. + + PrjState thisUntimed = this.getUntimedPrjState(); + PrjState otherUntimed = other.getUntimedPrjState(); + + if(!(thisUntimed.equals(otherUntimed))){ + return false; + } + + return subsetZone(other); + } + + /** + * Checks if all the zones are supersets (or equal to) the corresponding other zones as well + * as if the un-timed portions are equal. Note : it is assumed that both states have the same + * number of zones. + * @param other + * The state to compare against. + * @return + * True if zone zi is a superset of zone z'i for all i where zi is the i-th zone + * of this TimedPrjState and z'i is the i-th zone of the other TimedPrjState and + * the un-timed portion of the states are equal. + */ + public boolean superset(TimedPrjState other){ + // For clarity, extract the un-timed portions. Alternately, super.equals(otherState) would + // probably work. + + PrjState thisUntimed = this.getUntimedPrjState(); + PrjState otherUntimed = other.getUntimedPrjState(); + + if(!(thisUntimed.equals(otherUntimed))){ + return false; + } + + return supersetZone(other); + } + + /** + * Checks if all the zones are subsets (or equal to) the corresponding other zones. + * Note: The un-timed portion is not considered. It is assumed that each state has + * the same number of zones. + * @param other + * The state to compare against. + * @return + * True if zone zi is a subset of zone z'i for all i where zi is the i-th zone + * of this TimedPrjState and z'i is the i-th zone of the other TimedPrjState. + * False otherwise. + */ + public boolean subsetZone(TimedPrjState other){ + boolean result = true; + + for(int i=0; i + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zone; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.platuLpn.DualHashMap; +import edu.utah.ece.async.lema.verification.platu.platuLpn.VarSet; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.platu.stategraph.StateGraph; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zone.TimedState; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zone.Zone; + +/** + * Adds timing to a State. + * + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class TimedState extends State{ + + // Abstraction Function: + // This class follows the extension pattern for extending a base class. A TimedState + // adds a Zone for keeping track of timing relations. + + // A Zone for keeping track timing information. + private ZoneType _zone; + + // A ZoneGraph for storing a zone. + private ZoneGraph _graph; + + // Variable that determines whether zones or graph are being used. + private boolean _useGraph; + + // The state that this TimingState extends. + private State _state; + + @Override + public void setLpn(LPN thisLpn) { + _state.setLpn(thisLpn); + } + + @Override + public LPN getLpn() { + return _state.getLpn(); + } + + @Override + public void setLabel(String lbl) { + _state.setLabel(lbl); + } + + @Override + public String getLabel() { + return _state.getLabel(); + } + + @Override + public boolean[] getTranVector() { + return _state.getTranVector(); + } + + @Override + public void setIndex(int newIndex) { + _state.setIndex(newIndex); + } + + @Override + public int getIndex() { + return _state.getIndex(); + } + + @Override + public boolean hasNonLocalEnabled() { + return _state.hasNonLocalEnabled(); + } + + @Override + public void hasNonLocalEnabled(boolean nonLocalEnabled) { + _state.hasNonLocalEnabled(nonLocalEnabled); + } + + @Override + public boolean isFailure() { + return _state.isFailure(); + } + + @Override + public TimedState clone() { + // TODO: Ensure that the new TimedState contains its own copy of the zone. + if(_useGraph){ + return new TimedState(_state, _zone, true); + } + return new TimedState(_state, _zone, false); + } + + @Override + public String print() { + return _state.print(); + } + + @Override + public int hashCode() { + return _state.hashCode(); + } + + @Override + public boolean equals(Object obj) { + // TODO Check for completion. + if (this == obj) + return true; + + if (obj == null) + return false; + + if (getClass() != obj.getClass()) + return false; + + TimedState other = (TimedState) obj; + + if(!_state.equals(other._state)) + return false; + if(_useGraph){ + return _graph.equals(other._graph); + } + return _zone.equals(other._zone); + } + + @Override + public void print(DualHashMap VarIndexMap) { + _state.print(VarIndexMap); + } + + @Override + public int[] getMarking() { + return _state.getMarking(); + } + + @Override + public void setMarking(int[] newMarking) { + _state.setMarking(newMarking); + } + + @Override + public int[] getVariableVector() { + return _state.getVariableVector(); + } + + @Override + public HashMap getOutVector(VarSet outputs, + DualHashMap VarIndexMap) { + return _state.getOutVector(outputs, VarIndexMap); + } + + @Override + public State getLocalState() { + return _state.getLocalState(); + } + + + @Override + public String getEnabledSetString() { + return _state.getEnabledSetString(); + } + + @Override + public State update(StateGraph SG, HashMap newVector, + DualHashMap VarIndexMap) { + return _state.update(SG, newVector, VarIndexMap); + } + + @Override + public State update(HashMap newVector, + DualHashMap VarIndexMap, boolean[] newTranVector) { + return _state.update(newVector, VarIndexMap, newTranVector); + } + + @Override + public File serialize(String filename) throws FileNotFoundException, + IOException { + return _state.serialize(filename); + } + + @Override + public boolean failure() { + return _state.failure(); + } + + @Override + public void setFailure() { + _state.setFailure(); + } + + @Override + public void printStateInfo() { + _state.printStateInfo(); + } + + @Override + public ArrayList getTimeExtension() { + //return super.getTimeExtension(); + return _state.getTimeExtension(); + } + + @Override + public void setTimeExtension(ArrayList s) { + //super.setTimeExtension(s); + _state.setTimeExtension(s); + } + + @Override + public void addTimeExtension(TimedState s){ + //super.addTimeExtension(s); + _state.addTimeExtension(s); + } + + public TimedState(LPN lpn, int[] new_marking, int[] new_vector, + boolean[] new_isTranEnabled, boolean usegraph) { + super(lpn, new_marking, new_vector, new_isTranEnabled); + // TODO Find a way to remove the super call. + + _state = new State(lpn, new_marking, new_vector, new_isTranEnabled); + + _useGraph = usegraph; + + //_zone = new Zone(new State(lpn, new_marking, new_vector, new_isTranEnabled)); + + Zone newZone = new Zone(new State(lpn, new_marking, new_vector, new_isTranEnabled)); + + if(usegraph){ + _graph = ZoneGraph.extractZoneGraph(newZone); + } + else{ + _zone = newZone; + } + + //_state.setTimeExtension(this); + _state.addTimeExtension(this); + } + + /** + * Creates a timed state by adding an initial zone. + * @param other + * The current state. + */ + public TimedState(State other, boolean usegraph) { + super(other); + // TODO Find a way to remove the super call. + + _state = other; + + _useGraph = usegraph; + + //_zone = new Zone(other); + + Zone newZone = new Zone(other); + + if(usegraph){ + _graph = ZoneGraph.extractZoneGraph(newZone); + } + else{ + _zone = newZone; + } + + //_state.setTimeExtension(this); + _state.addTimeExtension(this); + } + + public TimedState(State s, ZoneType z, boolean usegraph) + { + super(s); + // TODO: Find a way to remove the super call. + _state = s; + + _useGraph = usegraph; + + if(usegraph && (z instanceof Zone)){ + _graph = ZoneGraph.extractZoneGraph((Zone) z); + } + else{ + _zone = z.clone(); + } + //_state.setTimeExtension(this); + _state.addTimeExtension(this); + } + + @Override + public String toString() + { + if(_useGraph){ + return _state.toString() + "\n" + _graph; + } + return _state.toString() + "\n" + _zone; + } + + public List getEnabledTransitionByZone() + { + if(_useGraph){ + return _graph.extractZone().getEnabledTransitions(); + } + return _zone.getEnabledTransitions(); + } + + public ZoneType getZone() + { + if(_useGraph){ + return _graph.extractZone(); + } + return _zone; + } + + public ZoneGraph getZoneGraph(){ + return _graph; + } + + public State getState() + { + return _state; + } + + + public boolean usingGraphs(){ + return _useGraph; + } + + public boolean untimedStateEquals(TimedState s){ + return this._state.equals(s._state); + } + + public boolean untimedStateEquals(State s){ + if(s instanceof TimedState){ + TimedState t = (TimedState) s; + return untimedStateEquals(t); + } + return this._state.equals(s); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/TimedStateSet.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/TimedStateSet.java new file mode 100644 index 000000000..ff2da535d --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/TimedStateSet.java @@ -0,0 +1,694 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zone; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map.Entry; + +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.logicAnalysis.StateSetInterface; +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.project.PrjState; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.EventSet; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.TimedPrjState; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.Zone; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class TimedStateSet extends HashSet implements StateSetInterface { + + + /* + * Abstraction Function: The StateSet object follows one of two modes for storing + * elements called the set mode and the subset/superset mode. In the set mode + * elements are simply stored in a HashSet _singletonList. In this + * mode the StateSet simply a wrapper of the HashSet and passes + * the operations to the _singletonList. + * + * In the subset/superset mode, elements are stored in _setList. The idea of is + * to be able to take the un-timed portion of a TimedPrjState (which can be thought + * of as a PrjState) use it as a key and have return all TimedPrjStates in the + * StateSet that share the same un-timed portion. Thus the key value pair + * (k, v) of the HashMap should be such that v is a list containing only + * TimedPrjStates that have the same un-timed portion k. + */ + + /* + * Representation Invariant: Only one of _singletonList or _setList should + * be non-null at a time and should correspond to whether the StateSet is in the + * subset/superset mode or not. Furthermore, if the StateSet is operating in the + * subset/superset mode, then it is the _setList that should be non-null. + * The mode is set in the constructor and should not change as long as the object + * is in existence. + * + * In the set mode, operations should be simply passed to the _singletonList + * thereby ensuring that the StateSet acts identical to a HashSet in this mode. + * + * Given a key value pair (k, v) stored in the _setList, the LinkedList v should + * only contain TimedPrjStates that have an un-timed portion equal to k. Specifically, + * s.getUntimedPrjState.equals(k) should return true for each TimedState in v. + */ + + /** + * + */ + private static final long serialVersionUID = 1L; + protected HashSet _singletonList; + protected HashMap> _setList; + + // Caches whether subsets, supersets, and timing is being used. + private boolean timed, subsets, supersets; + + + /** + * Creates a state set. The StateSet will be initialized into the into the subset/superset + * mode if the expression + * Options.getImingAnalysisFlag() && (ZoneType.getSubsetFlag() || + * ZoneType.getSupersetFlag()) + * is true. Otherwise the StateSet will be initialized into the set mode. Once the + * StateSet is initialized in the set mode or the subset/superset mode, it cannot be + * changed. + */ + public TimedStateSet(){ + + // Store that status when StateSet is initialized to avoid unexpected behavior. + timed = Options.getTimingAnalysisFlag(); + subsets = Zone.getSubsetFlag(); + supersets = Zone.getSupersetFlag(); + + if(timed && (subsets || supersets)){ + _setList = new HashMap>(); + } + else{ + _singletonList = new HashSet(); + } + } + +// public StateSet(boolean map){ +// if(map){ +// _setList = new HashMap>(); +// } +// else{ +// _singletonList = new HashSet(); +// } +// } + + /** + * Determines whether the any PrjStates are in the StateSet. + * @return + * True if any PrjStates are in the StateSet, false otherwise. + */ + @Override + public boolean isEmpty(){ + if(_singletonList != null){ + return _singletonList.isEmpty(); + } + return _setList.isEmpty(); + } + + /** + * Determines how many PrjStates are in the StateSet. + * @return + * A non-negative integer that gives the number of PrjStates are in the StateSet. + */ + @Override + public int size(){ + if(_singletonList != null){ + return _singletonList.size(); + } + int result = 0; + + for(LinkedList l : _setList.values()){ + result += l.size(); + } + + return result; + } + + /** + * Adds a PrjState to the StateSet. + * @param s + * The PrjState to add to the StateSet. + * @return + * True if the StateSet changes by adding the element s. + */ + @Override + public boolean add(PrjState s){ + + if(_singletonList != null){ + return _singletonList.add(s); + } + + if(_setList != null){ + + if(!(s instanceof TimedPrjState)){ + throw new IllegalArgumentException("Subset/superset mode set, but an un-timed" + + "state is being added."); + } + + TimedPrjState ts = (TimedPrjState) s; + + PrjState untimedState = ts.getUntimedPrjState(); + + LinkedList list = _setList.get(untimedState); + + if(list == null){ + + // No list is associated with this set of un-timed (local) states. + // So create a new list with this PrjState. + LinkedList newList = new LinkedList(); + newList.add(ts); + _setList.put(untimedState, newList); + + // The list changed, so return true; + return true; + } + +// if(list.contains(ts)){ +// // The set already contains the timed project state. So nothing changes. +// return false; +// } + + // Get an iterator from the list to allow removal of elements as the list is + // traversed. + Iterator iterate = list.iterator(); + + while(iterate.hasNext()){ + TimedPrjState listState = iterate.next(); + + // If subsets are selected and the state is a subset, then no need to add the + // state. Return false. + if(subsets && ts.subset(listState)){ + return false; + } + + if(ts.equals(listState)){ + return false; + } + + // If supersets are selected, items that are subsets of the new state may be + // removed. + if(supersets){ + + // We may remove any state that the current state is a superset of. + // If this state is not present, then it will eventually make it + // to the add. + if(ts.superset(listState)){ + + if(Options.getOutputSgFlag()){ + // Need to move the transitions form the old state and put it on + // the new state. + + // Update the transitions from the old state. + HashMap nextStates = listState.getNextGlobalStateMap(); + + // Add these transitions to the new state. + for(Entry e : nextStates.entrySet()){ + ts.addNextGlobalState(e.getKey(), e.getValue()); + } + + // Update the previous states. + HashMap> previousStates = + listState.get_previousProjectState(); + + // Each state in the HashSet, need to replace the previous + // reference to the old state with the new state. + for(EventSet es: previousStates.keySet()){ + for (TimedPrjState tps : previousStates.get(es)){ + // Add this previous state to the list of the new state. + ts.addPreviousState(es, tps); + + // Replace the edge to the old state with the new state. + tps.getNextGlobalStateMap().put(es, ts); + } + } + + } + + iterate.remove(); + } + } + } + + // The set does not already contain the timed project state. So add it. + list.add(ts); + + + return true; + } + + throw new IllegalStateException("Add was used and StateSet was not initialized."); + } + +// public boolean add(PrjState s){ +// if(s instanceof TimedPrjState){ +// TimedPrjState ts = (TimedPrjState) s; +// return add(ts); +// } +// else if(_singletonList == null){ +// throw new IllegalArgumentException("StateSet initialized in subset/superset mode," + +// " but only an un-timed state is being added."); +// } +// +// return _singletonList.add(s); +// } +// +// +// public boolean add(TimedPrjState s){ +// if(_setList == null){ +// throw new IllegalArgumentException("StateSet initialized as un-timed, " + +// " but a timed project state is attempted to be added."); +// } +// +// PrjState untimedState = s.getUntimedPrjState(); +// +// LinkedList list = _setList.get(untimedState); +// +// if(list == null){ +// +// // No list is associated with this set of un-timed (local) states. +// // So create a new list with this PrjState. +// LinkedList newList = new LinkedList(); +// newList.add(s); +// _setList.put(untimedState, newList); +// +// // The list changed, so return true; +// return true; +// } +// +// if(list.contains(s)){ +// // The set already contains the timed project state. So nothing changes. +// return false; +// } +// else{ +// // The set does not already contain the timed project state. So add it. +// list.add(s); +// } +// +// +// return true; +// } + + /** + * Overrides the HashSet version of the contains method since TimedStateSets + * handle containment a little differently. + */ + @Override + public boolean contains(Object obj){ + if(!(obj instanceof PrjState)){ + return false; + } + + return contains((PrjState) obj); + } + + /** + * Determines whether the StateSet contains the PrjState or not. + * @param s + * The PrjState to determine if the PrjState contains it. + * @return + * True if s is in the PrjState, false otherwise. + */ + @Override + public boolean contains(PrjState s){ + if(_singletonList != null){ + return _singletonList.contains(s); + } + + if(_setList != null){ + // If _setList != null, then StateSet has been initialized into subset/superset mode. + // Thus there are three possibilities : subsets has been selected, supersets has been + // selected, or both subsets and supersets have been selected. + + + if(!(s instanceof TimedPrjState)){ + throw new IllegalArgumentException("Subset/superset mode set, but an un-timed" + + "state is being added."); + } + + TimedPrjState ts = (TimedPrjState) s; + + // Get the un-timed portion for the cache. + PrjState untimedState = ts.getUntimedPrjState(); + + // Get the list keyed to this set of (local) un-timed states. + LinkedList list = _setList.get(untimedState); + + if(list == null){ + + // No list is associated with this set of un-timed (local) states. + // So the timed state cannot be in the set. + + return false; + } + + // Get an iterator from the list to allow removal of elements as the list is + // traversed. + Iterator iterate = list.iterator(); + + boolean result = false; + + while(iterate.hasNext()){ + TimedPrjState listState = iterate.next(); + + // If subsets are selected, then iteration can be exited as soon as a subset is found. + if(subsets && ts.subset(listState)){ + return true; + } + + if(ts.equals(listState)){ + return true; + } + + // If supersets are selected, items that are subsets of the new state may be + // removed. +// if(supersets){ +// if(!subsets && ts.equals(listState)){ +// // When an equal state is found, the return value must be true and the +// // state should not be removed. When not doing subsets, the superset check +// // cannot end here (since other sets that are supersets may exist further in the +// // list). If control has passed here, it can be deduced that subsets has not +// // been selected even without the subset flag since the +// // if(subsets && s.subset(listState) would have already been taken. +// // The subset flag is added here to allow a quick out of the extra equality check. +// result |= true; +// } +// else if(ts.superset(listState)){ +// // The new state (s) is a strict superset of an existing state. +// // Remove the existing state. +// iterate.remove(); +// } +// } + + } + + return result; + } + + throw new IllegalStateException("Contains was called and StateSet was not initialized."); + } + + +// public boolean contains(PrjState s){ +// if(s instanceof TimedPrjState){ +// TimedPrjState ts = (TimedPrjState) s; +// return contains(ts); +// } +// else if(_singletonList == null){ +// throw new IllegalArgumentException("StateSet initialized as timed," + +// " but only an untimed state is being added."); +// } +// +// return _singletonList.contains(s); +// } +// +// public boolean contains(TimedPrjState s){ +// if(_setList == null){ +// throw new IllegalArgumentException("StateSet initialized as untimed, " + +// " but a timed project state is attempted to be added."); +// } +// +// // If _setList == null, then StateSet has been initialized into subset/superset mode. +// // Thus there are three possibilities : subsets has been selected, supersets has been +// // selected, or both subsets and supersets have been selected. +// +// // Get the un-timed portion for the cache. +// PrjState untimedState = s.getUntimedPrjState(); +// +// // Get the list keyed to this set of (local) untimed states. +// LinkedList list = _setList.get(untimedState); +// +// if(list == null){ +// +// // No list is associated with this set of un-timed (local) states. +// // So the timed state cannot be in the set. +// +// return false; +// } +// +// //return list.contains(s); +// +// // Get an iterator from the list to allow removal of elements as the list is +// // traversed. +// Iterator iterate = list.iterator(); +// +// boolean result = false; +// +// while(iterate.hasNext()){ +// TimedPrjState listState = iterate.next(); +// +// // If subsets are selected, then iteration can be exited as soon as a subset is found. +// if(subsets && s.subset(listState)){ +// return true; +// } +// +// // If supersets are selected, items that are subsets of the new state may be +// // removed. +// if(supersets){ +// if(!subsets && s.equals(listState)){ +// // When an equal state is found, the return value must be true and the +// // state should not be removed. When not doing subsets, the superset check +// // cannot end here (since other sets that are supersets may exist further in the +// // list). If control has passed here, it can be deduced that subsets has not +// // been selected even without the subset flag since the +// // if(subsets && s.subset(listState) would have already been taken. +// // The subset flag is added here to allow a quick out of the extra equality check. +// result |= true; +// } +// else if(s.superset(listState)){ +// // The new state (s) is a strict superset of an existing state. +// // Remove the existing state. +// iterate.remove(); +// } +// } +// +// } +// +// return result; +// } + + /** + * Converts the StateSet into a HashSet. + * @return + * A HashSet containing the same PrjStates as the StateSet. + */ + public HashSet toHashSet(){ + if(_singletonList != null){ + return _singletonList; + } + HashSet result = new HashSet(); + //throw new IllegalStateException("Array initialized in subset/superset mode."); + for(LinkedList list : _setList.values()){ + result.addAll(list); + } + return result; + } + + @Override + public String toString(){ + + String result = ""; + + if(_singletonList != null){ + result += "# of prjStates found: " + size(); + } + + if(_setList != null){ + // Report the total number of project states found. + result += "# of timedPrjStates found: " + size(); + + // Report the number of un-timed states. + result += ", # of untimed states found: " + _setList.size(); + + // Report the largest Zone used. + result += ", Largest zone: " + Zone.ZoneSize; + } + + return result; + } + + /* + * (non-Javadoc) + * @see java.lang.Iterable#iterator() + */ + @Override + public Iterator iterator(){ + Iterator hashIterator = null; + Iterator> listIterator = null; + + if(_singletonList != null){ + hashIterator = _singletonList.iterator(); + } + + if(_setList != null){ + listIterator = _setList.values().iterator(); + } + + + return new StateSetIterator(hashIterator, listIterator); + } + + /** + * This is the particular version of the iterator that the StateSet uses. + * @author Andrew N. Fisher + * + */ + private class StateSetIterator implements Iterator{ + + /* + * Abstraction Function: + * A StateSetIterator is the implementation for the Iterator + * required by StateSet being iterable. The StateSet has two modes, + * one where a HashSet is used and one where a + * HashMap> is used. Correspondingly, + * This iterator has two modes. One that is meant iterate through the + * HashSet and the other that is meant to iterate through the HashMap. + * The member variable _hashIterator is simply the HashSet's own iterator. + * The member variables _hashListIterator and _listIterator together + * iterate through all the TimedPrjStates that are stored in the LinkedLists + * of a HashMap>. The _hashListIterator + * iterator goes through each of the LinkedList and the _listIterator goes + * through a single list. Thus the idea is to get the first LinkedList, + * traverse its elements, get the second LinkedList, traverse its elements + * and so on until all elements of the LinkedLists have been traversed. + */ + + + /* + * Representation Invariant : Only one of _hashIterator or _hashListIterator + * should be non-null at one time. The iterator should be iterating through + * one mode at a time, either the HashSet mode or the LinkedList mode. + * + * If _hashListIterator is not null, then _listIterator should either + * be the iterator for the last LinkedList returned by _hashListIterator + * or an iterator that has not exhausted all its elements. The idea is + * the _listIterator should be able to give the next element that is to + * be return if there are still elements that can be returned. + */ + + Iterator _hashIterator; + Iterator> _hashListIterator; + Iterator _listIterator; + + /** + * Initializes the iterator. Only one parameter should be non-null when this + * object is created matching one of the two modes of the StateSet object, + * it throws an IllegalStateExceptoin otherwise. + * @param hashIterator + * Iterator for a HashSet>. + */ + private StateSetIterator(Iterator hashIterator, + Iterator> listIterator){ + + // This method initializes the iterator for the StateSet. It initializes + // the iterator member variables. The member variables that are initialized + // should match the mode that the StateSet is in. This method may be made + // to check the member variables directly, but currently determines things + // by the variables passed. The HashIterator should be an iterator for the + // __singletonList member variable of the StateSet and the listIterator + // should be an iterator for the _setList member variable of the StateSet. + // In keeping with only one mode being initialized, only one of the member + // variables can be non-null. + if(hashIterator != null && listIterator !=null){ + throw new IllegalStateException("Only one iterator should be non-null."); + } + + _hashIterator = hashIterator; + _hashListIterator = listIterator; + + + if(_hashListIterator != null && _hashListIterator.hasNext()){ + _listIterator = _hashListIterator.next().iterator(); + + // Find the first list with an element or end with the last list. + while( !_listIterator.hasNext() && _hashListIterator.hasNext()){ + _listIterator = _hashListIterator.next().iterator(); + } + } + } + + /* + * (non-Javadoc) + * @see java.util.Iterator#hasNext() + */ + @Override + public boolean hasNext() { + + if(_hashIterator !=null){ + return _hashIterator.hasNext(); + } + + if(_listIterator == null){ + return false; + } + + return _listIterator.hasNext(); + } + + /* + * (non-Javadoc) + * @see java.util.Iterator#next() + */ + @Override + public PrjState next() { + + if(_hashIterator != null){ + return _hashIterator.next(); + } + + PrjState nextState = _listIterator.next(); + + // If this list is exhausted, find the next list with elements or + // get the last list. + while( !_listIterator.hasNext() && _hashListIterator.hasNext()){ + _listIterator = _hashListIterator.next().iterator(); + } + + return nextState; + } + + /* + * (non-Javadoc) + * @see java.util.Iterator#remove() + */ + @Override + public void remove() { + if(_hashIterator != null){ + _hashIterator.remove(); + return; + } + + // TODO: This has the following flaw currently. Suppose list1 and lists2 are two + // nonempty consecutive lists. Once next is called on the last element in list1, + // list2 becomes the new _listIterator. If removed is called, it will be called on list2 + // instead of list1 causing an error. + if(_hashListIterator != null){ + _listIterator.remove(); + } + + throw new UnsupportedOperationException("The iterator was not initialized."); + } + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/Zone.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/Zone.java new file mode 100644 index 000000000..ab48937c7 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/Zone.java @@ -0,0 +1,1836 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zone; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +import javax.swing.JOptionPane; + +import edu.utah.ece.async.lema.verification.lpn.ExprTree; +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; + + +/** + * This class is for storing and manipulating timing zones via difference bound matrices. + * The underlying structure is backed by linked lists which yields the name + * DBMLL (difference bound matrix linked list). A difference bound matrix has the form + * t0 t1 t2 t3 + * t0 m00 m01 m02 m03 + * t1 m10 m11 m12 m13 + * t2 m20 m21 m22 m23 + * t3 m30 m31 m32 m33 + * where tj - ti<= mij. In particular, m0k is an upper bound for tk and -mk is a lower + * bound for tk. + * + * The timers are referred to by an index. + * + * This class also contains a public nested class DiagonalNonZeroException which extends + * java.lang.RuntimeException. This exception may be thrown if the diagonal entries of a + * zone become nonzero. + * + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Zone extends ZoneType { + + // Abstraction Function : + // The difference bound matrix is represented by int[][]. + // In order to keep track of the upper and lower bounds of timers from when they are first + // enabled, the matrix will be augmented by a row and a column. The first row will contain + // the upper bounds and the first column will contain the negative of the lower bounds. + // For one timer t1 that is between 2 and 3, we might have + // lb t0 t1 + // ub x 0 3 + // t0 0 m m + // t1 -2 m m + // where x is not important (and will be given a zero value), 3 is the upper bound on t1 + // and -2 is the negative of the lower bound. The m values represent the actual difference + // bound matrix. Also note that the column heading are not part of the stored representation + // lb stands for lower bound while ub stands for upper bound. + // This upper and lower bound information is called the Delay for a Transition object. + // Since a timer is tied directly to a Transition, the timers are index by the corresponding + // Transition's index in a LPNTranslator. + // The timers are named by an integer referred to as the index. The _indexToTimer array + // connects the index in the DBM sub-matrix to the index of the timer. For example, + // a the timer t1 + + // Representation invariant : + // Zones are immutable. + // Integer.MAX_VALUE is used to logically represent infinity. + // The lb and ub values for a timer should be set when the timer is enabled. + // A negative hash code indicates that the hash code has not been set. + // The index of the timer in _indexToTimer is the index in the DBM and should contain + // the zeroth timer. + // The array _indexToTimer should always be sorted. + + /* The lower and upper bounds of the times as well as the dbm. */ + private int[][] _matrix; + + /* Maps the index to the timer. The index is row/column of the DBM sub-matrix. + * Logically the zero timer is given index -1. + * */ + private int[] _indexToTimer; + + /* The hash code. */ + private int _hashCode; + + /* A lexicon between a transitions index and its name. */ + private static HashMap _indexToTransition; + + /* Set if a failure in the testSplit method has fired already. */ + private static boolean _FAILURE = false; + + /* Hack to pass a parameter to the equals method though a variable */ + //private boolean subsetting = false; + + /** + * Construct a zone that has the given timers. + * @param timers + * The ith index of the array is the index of the timer. For example, + * if timers = [1, 3, 5], then the zeroth row/column of the DBM is the + * timer of the transition with index 1, the first row/column of the + * DBM is the timer of the transition with index 3, and the 2nd + * row/column is the timer of the transition with index 5. Do not + * include the zero timer. + * @param matrix + * The DBM augmented with the lower and upper bounds of the delays for the + * transitions. For example, suppose a zone has timers [1, 3, 5] (as + * described in the timers parameters). The delay for transition 1 is + * [1, 3], the delay for transition 3 is [2,5], and the delay for + * transition 5 is [4,6]. Also suppose the DBM is + * t0 t1 t3 t5 + * t0 | 0, 3, 3, 3 | + * t1 | 0, 0, 0, 0 | + * t3 | 0, 0, 0, 0 | + * t5 | 0, 0, 0, 0 | + * Then the matrix that should be passed is + * lb t0 t1 t3 t5 + * ub| 0, 0, 3, 5, 6| + * t0| 0, 0, 3, 3, 3| + * t1|-1, 0, 0, 0, 0| + * t3|-2, 0, 0, 0, 0| + * t5|-4, 0, 0, 0, 0| + * The matrix should be non-null and the zero timer should always be the + * first timer, even when there are no other timers. + */ + public Zone(int[] timers, int[][] matrix) + { + // A negative number indicates that the hash code has not been set. + _hashCode = -1; + + // Make a copy to reorder the timers. + _indexToTimer = Arrays.copyOf(timers, timers.length); + + // Sorting the array. + Arrays.sort(_indexToTimer); + + //if(_indexToTimer[0] != 0) + if(_indexToTimer[0] != -1) + { + // Add the zeroth timer. + int[] newIndexToTimer = new int[_indexToTimer.length+1]; + for(int i=0; i<_indexToTimer.length; i++) + { + newIndexToTimer[i+1] = _indexToTimer[i]; + } + + _indexToTimer = newIndexToTimer; + _indexToTimer[0] = -1; + } + +// if(_indexToTimer[0] < 0) +// { +// throw new IllegalArgumentException("Timers must be non negative."); +// } +// // Add a zero timer. +// else if(_indexToTimer[0] > 0) +// { +// int[] newTimerIndex = new int[_indexToTimer.length+1]; +// for(int i=0; i<_indexToTimer.length; i++) +// { +// newTimerIndex[i+1] = _indexToTimer[i]; +// } +// } + + // Map the old index of the timer to the new index of the timer. + HashMap newIndex = new HashMap(); + + // For the old index, find the new index. + for(int i=0; i(); + + // Get the transitions. + allTran = lpn.getAllTransitions(); + + for(Transition T : allTran) + { + _indexToTransition.put(T.getIndex(), T); + } + } + + _hashCode = -1; + + //_indexToTimer = initialState.getTranVector(); + + boolean[] enabledTran = initialState.getTranVector(); + +// int count = 0; +// +// // Find the size of the enabled transitions. +// for(int i=0; i indexToTran = new TreeMap(); + //_indexToTransition = new HashMap(); + + // Get out the Transitions to compare with the enableTran to determine which are + // enabled. + //Transition[] allTran = lpn.getAllTransitions(); + + HashMap enabledTranMap = new HashMap(); + + for(Transition T : allTran) + { + int index = T.getIndex(); + if(enabledTran[index]) + { + //indexToTran.put(index, T); + enabledTranMap.put(index, T); + } + } + + // Enabled timers plus the zero timer. + //_indexToTimer = new int[indexToTran.size()+1]; + //_indexToTimer = new int[_indexToTransition.size()+1]; + _indexToTimer = new int[enabledTranMap.size()+1]; + _indexToTimer[0] = -1; + + // Load the indices starting at index 1, since the zero timer will + // be index 0. + int count =1; + + // Load the indices of the Transitions into _indexToTimer. + //for(int i : indexToTran.keySet()) + //for(int i : _indexToTransition.keySet()) + for(int i : enabledTranMap.keySet()) + { + _indexToTimer[count] = i; + + count++; + } + + Arrays.sort(_indexToTimer); + + _matrix = new int[matrixSize()][matrixSize()]; + + for(int i=1; i varValues = + lpn.getAllVarsWithValuesAsString(initialState.getVariableVector()); + + // Set the upper and lower bound. + int upper, lower; + if(delay.getOp().equals("uniform")) + { + ExprTree lowerDelay = delay.getLeftChild(); + ExprTree upperDelay = delay.getRightChild(); + + lower = (int) lowerDelay.evaluateExpr(varValues); + upper = (int) upperDelay.evaluateExpr(varValues); + } + else + { + lower = (int) delay.evaluateExpr(varValues); + + upper = lower; + } + + setLowerBoundbydbmIndex(i, lower); + setUpperBoundbydbmIndex(i, upper); + } + + // Advance the time and tighten the bounds. + advance(); + recononicalize(); + + } + + /** + * Zero argument constructor for use in methods that create Zones where the members + * variables will be set by the method. + */ + private Zone() + { + _matrix = new int[0][0]; + _indexToTimer = new int[0]; + _hashCode = -1; + } + + /** + * Logically the DBM is the sub-matrix of _matrix obtained by removing the zeroth + * row and column. This method retrieves the (i,j) element of the DBM. + * @param i + * The i-th row of the DBM. + * @param j + * The j-th column of the DBM. + * @return + * The (i,j) element of the DBM. + */ +// public int getDBMIndex(int i, int j) +// { +// return _matrix[i+1][j+1]; +// } + + /** + * Logically the DBM is the sub-matrix of _matrix obtained by removing the zeroth + * row and column. This method sets the (i,j) element of the DBM. + * @param i + * The ith row of the DBM. + * @param j + * The jth column of the DBM. + * @param value + * The value of the matrix. + */ +// private void setDBMIndex(int i, int j, int value) +// { +// _matrix[i+1][j+1] = value; +// } + + /* (non-Javadoc) + * @see verification.timed_state_exploration.zone.ZoneType#getUpperBoundbyTransitionIndex(int) + */ + @Override + public int getUpperBoundbyTransitionIndex(int timer) + { + return getUpperBoundbydbmIndex(Arrays.binarySearch(_indexToTimer, timer)); + } + + /* (non-Javadoc) + * @see verification.timed_state_exploration.zone.ZoneType#getUpperBoundbydbmIndex(int) + */ + @Override + public int getUpperBoundbydbmIndex(int index) + { + return _matrix[0][dbmIndexToMatrixIndex(index)]; + } + + /** + * Set the value of the upper bound for the delay. + * @param timer + * The timer's index. + * @param value + * The value of the upper bound. + */ + public void setUpperBoundbyTransitionIndex(int timer, int value) + { + setUpperBoundbydbmIndex(Arrays.binarySearch(_indexToTimer, timer), value); + } + + /** + * Set the value of the upper bound for the delay. + * @param index + * The timer's row/column of the DBM matrix. + * @param value + * The value of the upper bound. + */ + public void setUpperBoundbydbmIndex(int index, int value) + { + _matrix[0][dbmIndexToMatrixIndex(index)] = value; + } + + /* (non-Javadoc) + * @see verification.timed_state_exploration.zone.ZoneType#getLowerBoundbyTransitionIndex(int) + */ + @Override + public int getLowerBoundbyTransitionIndex(int timer) + { + return -1*getLowerBoundbydbmIndex(Arrays.binarySearch(_indexToTimer, timer)); + } + + /* (non-Javadoc) + * @see verification.timed_state_exploration.zone.ZoneType#getLowerBoundbydbmIndex(int) + */ + @Override + public int getLowerBoundbydbmIndex(int index) + { + return _matrix[dbmIndexToMatrixIndex(index)][0]; + } + + /** + * Set the value of the lower bound for the delay. + * @param timer + * The timer's index. + * @param value + * The value of the lower bound. + */ + public void setLowerBoundbyTransitionIndex(int timer, int value) + { + setLowerBoundbydbmIndex(Arrays.binarySearch(_indexToTimer,timer), value); + } + + /** + * Set the value of the lower bound for the delay. + * @param index + * The timer's row/column of the DBM matrix. + * @param value + * The value of the lower bound. + */ + public void setLowerBoundbydbmIndex(int index, int value) + { + _matrix[dbmIndexToMatrixIndex(index)][0] = -1*value; + } + + /** + * Converts the index of the DBM to the index of _matrix. + * @param i + * The row/column index of the DBM. + * @return + * The row/column index of _matrix. + */ + private static int dbmIndexToMatrixIndex(int i) + { + return i+1; + } + + /* (non-Javadoc) + * @see verification.timed_state_exploration.zone.ZoneType#getdbm(int, int) + */ + @Override + public int getDbmEntry(int i, int j) + { + return _matrix[dbmIndexToMatrixIndex(i)][dbmIndexToMatrixIndex(j)]; + } + + /** + * Sets an entry of the DBM using the DBM's addressing. + * @param i + * The row of the DBM. + * @param j + * The column of the DBM. + * @param value + * The new value for the entry. + */ + private void setDbmEntry(int i, int j, int value) + { + _matrix[dbmIndexToMatrixIndex(i)][dbmIndexToMatrixIndex(j)] = value; + } + + /** + * Converts the index of the timer from the _indexToTimer array to the index of _matrix. + * @param i + * The index of the timer from the _indexToTimer array. + * @return + * The index in the _matrix. + */ + @SuppressWarnings("unused") + private int timerIndexToMatrixIndex(int i) + { + //return i+2; + //return i+1; + return dbmIndexToMatrixIndex(Arrays.binarySearch(_indexToTimer, i)); + } + + /** + * Returns the index of the the transition in the DBM given the index of the + * transition. + * @param i + * The transition's index. + * @return + * The row/column of the DBM associated with the i-th transition. + */ + private int timerIndexToDBMIndex(int i) + { + return Arrays.binarySearch(_indexToTimer, i); + } + + /** + * Converts the index of _matrix to the index of the DBM. + * @param i + * The row/column index of _matrix. + * @return + * The row/column index of the DBM. + */ + @SuppressWarnings("unused") + private static int matrixIndexTodbmIndex(int i) + { + return i-1; + } + + /** + * The matrix labeled with 'ti' where i is the transition index associated with the timer. + */ + @Override + public String toString() + { + String result = "Timer and delay.\n"; + + int count = 0; + + // Print the timers. + for(int i=1; i<_indexToTimer.length; i++, count++) + { + if(_indexToTransition == null) + { + // If an index to transition map has not been set up, + // use the transition index for the timer. + result += " t" + _indexToTimer[i] + " : "; + } + else + { + result += " " + _indexToTransition.get(_indexToTimer[i]) + ":"; + } + result += "[ " + -1*getLowerBoundbydbmIndex(i) + ", " + getUpperBoundbydbmIndex(i) + " ]"; + + if(count > 9) + { + result += "\n"; + count = 0; + } + } + + result += "\nDBM\n"; + + //result += "|"; + + // Print the DBM. + for(int i=0; i<_indexToTimer.length; i++) + { + //result += " " + _matrix[i][0]; + result += "| " + getDbmEntry(i, 0); + + //for(int j=1; j<_indexToTimer.length; j++) + for(int j=1; j<_indexToTimer.length; j++) + { + //result += ", " + _matrix[i][j]; + result += ", " + getDbmEntry(i, j); + } + + result += " |\n"; + } + + //result += "|"; + + return result; + } + + /** + * Tests for equality. Overrides inherited equals method. + * @return True if o is equal to this object, false otherwise. + */ + @Override + public boolean equals(Object o) + { + // Check if the reference is null. + if(o == null) + { + return false; + } + + // Check that the type is correct. + if(!(o instanceof Zone)) + { + return false; + } + + // Check for equality using the Zone equality. + return equals((Zone) o); + } + + + /** + * Tests for equality. + * @param + * The Zone to compare. + * @return + * True if the zones are non-null and equal, false otherwise. + */ + public boolean equals(Zone otherZone) + { + // Check if the reference is null first. + if(otherZone == null) + { + return false; + } + + // Check for reference equality. + if(this == otherZone) + { + return true; + } + + // Check hash codes if not doing subsets. + //if(!ZoneType.getSubsetFlag()){ + //if(!subsetting){ + // If the hash codes are different, then the objects are not equal. + if(this.hashCode() != otherZone.hashCode()) + { + return false; + } + //} + + // Check if the timers are the same. +// if(!Arrays.equals(this._indexToTimer, otherZone._indexToTimer)) +// { +// return false; +// } + + if(this._indexToTimer.length != otherZone._indexToTimer.length){ + return false; + } + + for(int i=0; i getDbmEntry(i, k) + getDbmEntry(k, j)) + { + setDbmEntry(i, j, getDbmEntry(i, k) + getDbmEntry(k, j)); + } + + if( (i==j) && getDbmEntry(i, j) != 0) + { + throw new DiagonalNonZeroException("Entry (" + i + ", " + j + ")" + + " became " + getDbmEntry(i, j) + "."); + } + } + } + } + } + + /* (non-Javadoc) + * @see verification.timed_state_exploration.zone.ZoneType#exceedsLowerBoundbyTransitionIndex(int) + */ + @Override + public boolean exceedsLowerBoundbyTransitionIndex(int timer) + { + // TODO : Check if finished. + return exceedsLowerBoundbydbmIndex(Arrays.binarySearch(_indexToTimer, timer)); + } + + /* (non-Javadoc) + * @see verification.timed_state_exploration.zone.ZoneType#exceedsLowerBoundbydbmIndex(int) + */ + @Override + public boolean exceedsLowerBoundbydbmIndex(int index) + { + // TODO: Check if finished. + + // Note : Make sure that the lower bound is stored as a negative number + // and that the inequality is correct. + return _matrix[0][dbmIndexToMatrixIndex(index)] <= + _matrix[1][dbmIndexToMatrixIndex(index)]; + } + + /* (non-Javadoc) + * @see verification.timed_state_exploration.zone.ZoneType#fireTransitionbyTransitionIndex(int, int[], verification.platu.stategraph.State) + */ + @Override + public ZoneType fireTransitionbyTransitionIndex(int timer, int[] enabledTimers, + State state) + { + // TODO: Check if finish. + int index = Arrays.binarySearch(_indexToTimer, timer); + + //return fireTransitionbydbmIndex(Arrays.binarySearch(_indexToTimer, timer), + //enabledTimers, state); + + // Check if the value is in this zone to fire. + if(index < 0){ + return this; + } + + return fireTransitionbydbmIndex(index, enabledTimers, state); + } + + /* (non-Javadoc) + * @see verification.timed_state_exploration.zone.ZoneType#fireTransitionbydbmIndex(int, int[], verification.platu.stategraph.State) + */ + @Override + public ZoneType fireTransitionbydbmIndex(int index, int[] enabledTimers, + State state) + { + // TODO: Finish + Zone newZone = new Zone(); + + + // Copy over the enabledTimers adding a zero timer. + //newZone._indexToTimer = enabledTimers; + + newZone._indexToTimer = new int[enabledTimers.length+1]; + + // Put the _indexToTimer value for the zeroth timer to -1. + // See the Abstraction Function section at the top of the + // class for a discussion on why. + newZone._indexToTimer[0] = -1; + + + for(int i=0; i newTimers = new HashSet(); + HashSet oldTimers = new HashSet(); + + for(int i=0; i= 0 ) + { + // The timer was already present in the zone. + oldTimers.add(newZone._indexToTimer[i]); + } + else + { + // The timer is a new timer. + newTimers.add(newZone._indexToTimer[i]); + } + } + + // Create the new matrix. + newZone._matrix = new int[newZone.matrixSize()][newZone.matrixSize()]; + + // TODO: For simplicity, make a copy of the current zone and perform the + // restriction and re-canonicalization. Later add a copy re-canonicalization + // that does the steps together. + + Zone tempZone = this.clone(); + + tempZone.restrict(index); + tempZone.recononicalize(); + + // Copy the tempZone to the new zone. + for(int i=0; i indexToTran = new TreeMap(); +// +// // Get out the Transitions to compare with the enableTran to determine which are +// // enabled. +// Transition[] allTran = lpn.getAllTransitions(); +// +// for(Transition T : allTran) +// { +// int t = T.getIndex(); +// if(newTimers.contains(t)) +// { +// indexToTran.put(t, T); +// } +// } + + for(int i : newTimers){ + + // Get all the upper and lower bounds for the new timers. + // Get the name for the timer in the i-th column/row of DBM + //String tranName = indexToTran.get(i).getName(); + String tranName = _indexToTransition.get(i).getLabel(); + ExprTree delay = lpn.getDelayTree(tranName); + + // Get the values of the variables for evaluating the ExprTree. + HashMap varValues = + lpn.getAllVarsWithValuesAsString(state.getVariableVector()); + + // Set the upper and lower bound. + int upper, lower; + if(delay.getOp().equals("uniform")) + { + ExprTree lowerDelay = delay.getLeftChild(); + ExprTree upperDelay = delay.getRightChild(); + + lower = (int) lowerDelay.evaluateExpr(varValues); + upper = (int) upperDelay.evaluateExpr(varValues); + } + else + { + lower = (int) delay.evaluateExpr(varValues); + + upper = lower; + } + + newZone.setLowerBoundbyTransitionIndex(i, lower); + newZone.setUpperBoundbyTransitionIndex(i, upper); + + } + + newZone.advance(); + newZone.recononicalize(); + + // Run the test method. + //testSplit(newZone, true); + //testZoneGraphMinimization(newZone, true); + + return newZone; + } + + /** + * Merges this Zone with another Zone. + * @param otherZone + * The zone to merge with this Zone. + * @return + * The merged Zone. + */ + public ZoneType mergeZones(Zone otherZone) + { + // TODO: Finish. + + Zone mergedZone = new Zone(); + + //mergedZone._indexToTimer = mergeTimers(this._indexToTimer, otherZone._indexToTimer); + + /* Maps the index of this Zone's timers to the mergedZone. */ + //HashMap thisNewIndex; + + //thisNewIndex = makeIndexMap(this._indexToTimer, mergedZone._indexToTimer); + + /* Maps the index of otherZone Zone's timers to the mergeZone. */ + //HashMap otherNewIndex; + + //otherNewIndex = makeIndexMap(otherZone._indexToTimer, mergedZone._indexToTimer); + + //mergedZone._matrix = new int[mergedZone.matrixSize()][mergedZone.matrixSize()]; + + ZoneTriple[] zoneAndIndex = mergeTimers(otherZone); + + mergedZone._indexToTimer = new int[zoneAndIndex.length]; + + for(int i=0; i makeIndexMap(int[] baseTimers, int[] newTimers) + { + // Map the new index of the timer to the old timer. + HashMap newIndex = new HashMap(); + + // For the old index, find the new index. + for(int i=0; i getEnabledTransitions() + { + ArrayList enabledTransitions = new ArrayList(); + + // Check if the timer exceeds its lower bound staring with the first nonzero + // timer. + for(int i=1; i<_indexToTimer.length; i++) + { + if(getDbmEntry(0, i) >= -1 * getLowerBoundbydbmIndex(i)) + { + enabledTransitions.add(_indexToTransition.get(_indexToTimer[i])); + } + } + + return enabledTransitions; + } + + /* (non-Javadoc) + * @see verification.timed_state_exploration.zone.ZoneType#getLexicon() + */ + @Override + public HashMap getLexicon(){ + if(_indexToTransition == null){ + return null; + } + + return new HashMap(_indexToTransition); + } + + public static void setLexicon(HashMap lexicon){ + _indexToTransition = lexicon; + } + + /** + * Gives an array that maps the index of a timer in the DBM to the timer's index. + * @return + * The array that maps the index of a timer in the DBM to the timer's index. + */ + public int[] getIndexToTimer(){ + return Arrays.copyOf(_indexToTimer, _indexToTimer.length); + } + + //----------------------Inner Classes----------------------------------------------- + /** + * The DiagonalNonZeroException extends the java.lang.RuntimerExpcetion. + * The intention is for this exception to be thrown is a Zone has a non zero + * entry appear on the diagonal. + * + * @author Andrew N. Fisher + * + */ + public class DiagonalNonZeroException extends java.lang.RuntimeException + { + + /** + * Generated serialVersionUID. + */ + private static final long serialVersionUID = -3857736741611605411L; + + /** + * Creates a DiagonalNonZeroException. + * @param Message + * The message to be displayed when the exception is thrown. + */ + public DiagonalNonZeroException(String Message) + { + super(Message); + } + } + + /** + * This exception is thrown when trying to merge two zones whose corresponding timers + * do not agree. + * @author Andrew N. Fisher + * + */ + public class IncompatibleZoneException extends java.lang.RuntimeException + { + + /** + * Generated serialVersionUID + */ + private static final long serialVersionUID = -2453680267411313227L; + + + public IncompatibleZoneException(String Message) + { + super(Message); + } + } + + /** + * TODO + * @author Andrew N. Fisher + * + */ + private class ZoneTriple + { + + // Representation Invariant: + // If both _zone1 and _zone2 are non null, then this Zone should be + // in _zone1. + + private int _timer; + private ZoneType _zone1; + private int _index1; + private ZoneType _zone2; + private int _index2; + + public ZoneTriple (int timer, ZoneType zone, int index) + { + _timer = timer; + _zone1 = zone; + _index1 = index; + } + + public ZoneTriple(int timer, ZoneType zone1, int index1, ZoneType zone2, int index2) + { + _timer = timer; + _zone1 = zone1; + _index1 = index1; + _zone2 = zone2; + _index2 = index2; + } + + @SuppressWarnings("unused") + public ZoneType get_zone1() { + return _zone1; + } + + @SuppressWarnings("unused") + public void set_zone1(ZoneType _zone1) { + this._zone1 = _zone1; + } + + @SuppressWarnings("unused") + public int get_index1() { + return _index1; + } + + @SuppressWarnings("unused") + public void set_index1(int _index1) { + this._index1 = _index1; + } + + @SuppressWarnings("unused") + public ZoneType get_zone2() { + return _zone2; + } + + @SuppressWarnings("unused") + public void set_zone2(ZoneType _zone2) { + this._zone2 = _zone2; + } + + @SuppressWarnings("unused") + public int get_index2() { + return _index2; + } + + @SuppressWarnings("unused") + public void set_index2(int _index2) { + this._index2 = _index2; + } + + @SuppressWarnings("unused") + public int get_timer() { + return _timer; + } + + @SuppressWarnings("unused") + public void set_timer(int _timer) { + this._timer = _timer; + } + + @Override + public String toString() + { + String result= ""; + + result = "Timer : " + _timer + "\n"; + + if(_zone2 == null) + { + result += "In single zone : \n"; + result += "********************************\n"; + result += _zone1 + "\n"; + result += "++++++++++++++++++++++++++++++++\n"; + result += "Index : " + _index1 + "\n"; + result += "********************************\n"; + } + else + { + result += "In both zones : \n"; + result += "***First Zone*******************\n"; + result += _zone1 + "\n"; + result += "++++++++++++++++++++++++++++++++\n"; + result += "Index : " + _index1 + "\n"; + result += "********************************\n"; + result += "***Second Zone*******************\n"; + result += _zone2 + "\n"; + result += "++++++++++++++++++++++++++++++++\n"; + result += "Index : " + _index2 + "\n"; + result += "********************************\n"; + } + + return result; + } + } + + /** + * Tests ways of splitting a zone. + * @param z + * The Zone to split. + * @param popUps + * Enables pop up windows notifying that a zone failed. + */ + @SuppressWarnings("unused") + private static void testSplit(Zone z, boolean popUp) + { + // Get a new copy of the matrix to manipulate. + int[][] m = z._matrix; + + int[][] newMatrix = new int[m.length][m.length]; + + // Copy the matrix. + for(int i=0; i " + + "\"t" + _indexToTimer[j] + "\"" + + "[label=\"" + getDbmEntry(i,j) + "\"];"); + } + } + + // Terminate the main block + writer.print("}"); + } + + /** + * Clears out the lexicon. + */ + public static void clearLexicon(){ + _indexToTransition = null; + } +} \ No newline at end of file diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneGraph.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneGraph.java new file mode 100644 index 000000000..f5686f9d6 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneGraph.java @@ -0,0 +1,1184 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zone; + +import java.io.PrintStream; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.TreeSet; + +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; + +import java.util.ArrayList; + +/** + * + * Represents a zone with the minimum number of constraints. + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ZoneGraph{ + + /* + * Abstraction Function : + * + */ + + /* + * Representation Invariant : + * + */ + + /* List of nodes in the graph. */ + //ArrayList _graph; + HashMap _graph; + + + /* + * Temporary zone for calculations. The variable should be null when the ZoneGraph is + * stored to reduce memory requirements. + */ + Zone _tmpZone; + + /* A lexicon between a transitions index and its name. */ + private HashMap _indexToTransition; + + /* Cached hash code.*/ + int _hashCode; + + /* Maps the index to the timer. The index is row/column of the DBM sub-matrix. + * Logically the zero timer is given index -1. + * */ + private int[] _indexToTimer; + + /* + * Store the enabled upper and lower bounds of the timers. + */ + private HashMap _bounds; + + /** + * Zero argument constructor for use in methods that create ZoneGraphs where the members + * variables will be set by the method. + */ + private ZoneGraph(){ + //_graph = new ArrayList(); + _graph = new HashMap(); + _hashCode = -1; + _indexToTimer = new int[0]; + _indexToTransition = new HashMap(); + _bounds = new HashMap(); + } + + public ZoneGraph(int[] timers, int[][] matrix){ + + } + + public ZoneGraph(State initialState){ + + } + + public ZoneGraph(Zone z){ + _graph = extractZoneGraph(z)._graph; + } + + + + /* (non-Javadoc) + * @see java.lang.Object#clone() + */ + @Override + public ZoneType clone(){ + throw new UnsupportedOperationException(); + + //return null; + } + + @Override + public boolean equals(Object o) { + // Check if the reference is null. + if(o == null) + { + return false; + } + + // Check that the type is correct. + if(!(o instanceof ZoneGraph)) + { + return false; + } + + // Check for equality using the Zone equality. + return equals((ZoneGraph) o); + } + + /** + * Tests for equality. + * @param otherGraph + * @return + */ + public boolean equals(ZoneGraph otherGraph){ + + // Check if the reference is null first. + if(otherGraph == null) + { + return false; + } + + // Check for reference equality. + if(this == otherGraph) + { + return true; + } + + // If the hash codes are different, then the objects are not equal. + if(this.hashCode() != otherGraph.hashCode()) + { + return false; + } + + // Extract the Nodes. +// HashSet thisNodes = new HashSet(this._graph.values()); +// +// HashSet otherNodes = new HashSet(otherGraph._graph.values()); +// + // Check same number of nodes. +// if(thisNodes.size() != otherNodes.size()){ +// return false; +// } +// +// // Check that all the nodes are the same and their edges are the same. +// for(Node n : thisNodes){ +// if(!otherNodes.contains(n)){ +// return false; +// } +// } + + // Extract nodes. + HashMap thisNodes = new HashMap(); + + for(Node n : this._graph.values()){ + thisNodes.put(n, n); + } + + HashMap otherNodes = new HashMap(); + + for(Node n : otherGraph._graph.values()){ + otherNodes.put(n, n); + } + + if(thisNodes.size() != otherNodes.size()){ + return false; + } + + // Check if nodes and edges are the same. + for(Node n : thisNodes.keySet()){ + if(!otherNodes.containsKey(n)){ + return false; + } + + // Get the node from otherNodes. + Node oNode = otherNodes.get(n); + + // Check the edges for this node. + if(n._edges.size() != oNode._edges.size()){ + return false; + } + + for(Edge e : n._edges){ + if(!oNode._edges.contains(e)){ + return false; + } + } + } + + + return this._graph.equals(otherGraph._graph); + } + + @Override + public int hashCode() { + + // Check if the hash code has already be calculated. + if(_hashCode >=0){ + return _hashCode; + } + + // Set the hash code. + _hashCode = _graph.hashCode(); + + return _hashCode; + } + + @Override + public String toString() { + + return _graph.toString(); + } + + public static ZoneGraph extractZoneGraph(Zone z){ + + ZoneGraph newGraph = new ZoneGraph(); + + if(z.getLexicon() != null){ + newGraph._indexToTransition = z.getLexicon(); + } + + // Get the timer index. + newGraph._indexToTimer = z.getIndexToTimer(); + + newGraph._bounds = new HashMap(); + + + // Partition into zero-equivalence. + newGraph.createPartition(z); + + // Create the part of the graph that connects the partitions. + newGraph.connectPartition(z); + + // Create the part of the graph that lies in a partition. + HashSet nodes = new HashSet(newGraph._graph.values()); + for(Node n : nodes){ + n.connectInteralNodes(z); + } + + // Set the hash code to -1 to indicate that it has not been calculated yet. + newGraph._hashCode = -1; + +// for(Node n : nodes){ +// System.out.println(n); +// } + + // Get the upper and lower bounds. + for(int i=1; i timersList = new ArrayList(); +// for(Node n : _graph.values()){ +// timersList.addAll(n._partition); +// } +// +// int[] timers = new int[timersList.size()]; +// +// for(int i=0; i nodeSet = new HashSet(_graph.values()); + + Node[] nodes = nodeSet.toArray(new Node[0]); + + // This ensures that the zero timer is the first timer. + Arrays.sort(nodes); + + // Get all the timers. + ArrayList timersList = new ArrayList(); + for(Node n : nodes){ + timersList.addAll(n._partition); + } + + // Set up the timers array. Note the array does not include the zero timer. + int[] timers = new int[timersList.size()-1]; + + for(int i=0; i 2){ + if(n.size() > 1){ + for(int j=0; j 4 -- (2)--> 7 --(2)--> 1, + // I want the (1,4) entry of the DBM to be 3. Similarly the + // (4,7) entry of the DBM is 2 and the (7,1) entry is 2. + // To get the DBM index of the matrix, each index must be increased by + // 1. + //matrix[(i+1)+j][(i+1)+(j+1)%n.size()] = n.getInternalEdgeWeight(j); + matrix[(totalLength+1)+j][(totalLength+1)+(j+1)%n.size()] = + n.getInternalEdgeWeight(j); + } + } + + // Set up the weights between the Nodes. + for(Edge e : n.getEdges()){ + Node terminal = e.getTerminalNode(); + matrix[totalLength+1][timersList.indexOf(terminal.getLeastTimer())+1] + = e.getWeight(); + } + + totalLength += n.size(); + } + + Zone newZone = new Zone(timers, matrix); + + Zone.setLexicon(_indexToTransition); + + for(int i=1; i<_indexToTimer.length; i++){ + int timerIndex = _indexToTimer[i]; + intPair p = _bounds.get(timerIndex); + + newZone.setLowerBoundbyTransitionIndex(timerIndex, p.getLeftInt()); + newZone.setUpperBoundbyTransitionIndex(timerIndex, p.getRightInt()); + } + + //return new Zone(timers, matrix); + return newZone; + } + + public void clearZone(){ + _tmpZone = null; + } + + public void toDot(PrintStream writer){ + + // Write the header. + writer.println("digraph G {"); + + // Define the nodes. + HashSet nodes = new HashSet(_graph.values()); + + for(Node n : nodes){ + writer.println("\"t" + n.getLeastTimer() + "\"" + + "[label=\"" + n.partitionString() + "\"]"); + } + + // Print edges. + for(Node n : nodes){ + for(Edge e : n.getEdges()){ + writer.println("\"t" + n.getLeastTimer() + "\"" + "->" + + "\"t" + e.getTerminalNode().getLeastTimer() + "\"" + + "[label=\"" + e.getWeight() + "\"]"); + } + } + + // Close the main block. + writer.println("}"); + } + + /* + * Create nodes for each zero-equivalent classes. + */ + public void createPartition(Zone z){ + + // Put each timer in the correct partition. + //for(int i=0; i<_indexToTransition.size(); i++){ + for(int i=0; i<_indexToTimer.length; i++){ + boolean wasAdded = false; + + for(Node n : _graph.values()){ + wasAdded |= n.add(i, z); + if(wasAdded){ + _graph.put(i, n); + break; + } + } + + // If the element was not contained in any previous Node, then + // add a new node. + if(!wasAdded){ + _graph.put(i, new Node(i)); + } + } + } + + /** + * Add edges between nodes. + * + * @param z + * The zone for the connections. + */ + public void connectPartition(Zone z){ + int i=0, j=0; + HashSet nodes = new HashSet(_graph.values()); + + HashSet redundantPairs = getRedundantEdge(nodes, z); + + for(Node iNode : nodes){ + j=0; + int iTimer = iNode.getLeastTimer(); + for(Node jNode : nodes){ + int jTimer = jNode.getLeastTimer(); + if(i getLexicon(){ + return new HashMap (_indexToTransition); + } + + + private HashSet getRedundantEdge(HashSet nodes, Zone z){ + HashSet redundantEdges = new HashSet(); + + for(Node kNode : nodes){ + int k = kNode.getLeastTimer(); + for(Node iNode : nodes){ + int i = iNode.getLeastTimer(); + for(Node jNode : nodes){ + int j = jNode.getLeastTimer(); + if(z.getDbmEntry(i, k) != ZoneType.INFINITY && + z.getDbmEntry(k, j) != ZoneType.INFINITY + && z.getDbmEntry(i, j) > z.getDbmEntry(i, k) + z.getDbmEntry(k, j)) + { + //setDbmEntry(i, j, getDbmEntry(i, k) + getDbmEntry(k, j)); + redundantEdges.add(new intPair(i, j)); + } + } + } + } + + + return redundantEdges; + } + + //-------------------Inner Classes--------------------------------------------------- + /** + * A node of the graph. + * @author Andrew N. Fisher + * + */ + private class Node implements Comparable{ + + /* + * Abstraction Function : + * + */ + + /* + * Representation Invariant : + * + */ + + /* + * Label for the node. + */ + //String _name; + + /* + * List of out edges. + */ + ArrayList _edges; + + /* + * Previous nodes, ie list of nodes prevNode such that there is an edge + * from preNode to this node. + */ + //ArrayList _previousNode; + + /* The partition. */ + TreeSet _partition; + + /* The connecting edges in the node. The zero element gives the weight of the + * edge from the least timer ti in the _partition to tj the next timer in + * _partition, and so on. + */ + ArrayList _internalEdges; + + /* Cached hash code. Code should be -1 if not created yet. */ + int _nodeHashCode; + + @SuppressWarnings("unused") + public Node(String name){ + _edges = new ArrayList(); + //_previousNode = new ArrayList(); + _partition = new TreeSet(); + _nodeHashCode = -1; + + //_name = name; + } + + /** + * Create a node containing the timer i. + * @param i + * The element to start the node with. + */ + public Node(int i) { + _edges = new ArrayList(); + //_previousNode = new ArrayList(); + _partition = new TreeSet(); + _internalEdges = new ArrayList(); + _nodeHashCode = -1; // Indicates the hash code has not been calculated. + + _partition.add(i); + } + + /** + * Retrieve the smallest timer of the Node. + * @return + * The smallest timer contained in this Node. + */ + public int getLeastTimer() { + return _partition.first(); + } + + /** + * Gives the weight of the edge from the ith timer to the i+1st timer in the + * Node. + * @param i + * @return + * The weight of the edge from the ith timer to the i+1st timer in the Node. + */ + public int getInternalEdgeWeight(int i) { + + return _internalEdges.get(i); + } + + public int size(){ + return _partition.size(); + } + + /** + * Adds the element to the current node if the element is equivalent to the + * elements in the node. + * @param i + * The timer to add. + * @param z + * The zone to use for determining the equivalence. + * @return + * True if the element was added, false otherwise. + */ + public boolean add(int i, Zone z) { + + // Check if any elements are in the partition. + if(_partition.size() == 0){ + _partition.add(i); + return true; + } + + // Check if the element is already in the partition. + if(_partition.contains(i)){ + // Already in the set, no need to add it again. + return false; + } + + // Get the least value of the partition to check against. + int least = _partition.first(); + + int fromPartToi = z.getDbmEntry(least, i); + + int fromiToPart = z.getDbmEntry(i, least); + + if( fromPartToi == -1*fromiToPart){ + _partition.add(i); + return true; + } + + return false; + } + + + public ArrayList getEdges(){ + ArrayList newList = new ArrayList(); + + for(Edge e : _edges){ + newList.add(e); + } + + return newList; + } + + /** + * Connects the nodes in the partition. + * @param z + * The zone to get the connections from. + */ + public void connectInteralNodes(Zone z){ + + if(_partition.size() < 2){ + return; + } + + Iterator iteratePartition = _partition.iterator(); + + int i = iteratePartition.next(); + + int j = 0; + + while(iteratePartition.hasNext()){ + j = iteratePartition.next(); + _internalEdges.add(z.getDbmEntry(i, j)); + + i = j; + } + + j = _partition.first(); + + _internalEdges.add(z.getDbmEntry(i, j)); + } + + /** + * Overrides Object's toString(). + */ +// public String toString(){ +// String s =""; +// +// // Print name. +// s += "Node : " + _name + "\n"; +// +// // Print next nodes. +// s += "Next nodes : \n"; +// +// for(Edge e : _edges){ +// s += e.toString(); +// } +// +// // Print previous nodes. +// for(Node n : _previousNode){ +// s += n._name; +// } +// +// return s; +// } + + /** + * Overrides the Object's toString method. + */ + @Override + public String toString(){ + String result = "------------------------\n Partition nodes." + + "\n------------------------\n"; + + // Print the partition. + if(_partition.size() < 2 && _partition.size() > 0){ + + result += _partition.first() + "\n"; + } + else if(_internalEdges.size()>0){ + Iterator iteratePartition = _partition.iterator(); + + int k = iteratePartition.next(); + + int j = 0, i=k, l=0; + + while(iteratePartition.hasNext()){ + j = iteratePartition.next(); + result += "" + i + "-" + _internalEdges.get(l) + "->" + j + "\n"; + + i = j; + l++; + } + + //j = _partition.first(); + + result += "" + i + "-" + _internalEdges.get(l) + "->" + k + "\n"; + } + else{ + for(Integer i : _partition){ + result += "" + i + " "; + } + + result += "\n"; + } + + result += "\n----------------------\n Out Edges \n --------------------------\n"; + + for(Edge e : _edges){ + result += e.toString() + "\n"; + } + + result += "\n"; + return result; + } + + /** + * Creates a string representation of the partition. + * @return + * A string of the for {x, y, ...} where x, y, etc. are the elements + * of the partition. + */ + public String partitionString(){ + + String result = "["; + + if(_partition.size() > 0){ + Iterator partition = _partition.iterator(); + + result += " " + _indexToTimer[partition.next()]; + + while(partition.hasNext()){ + result += ", " + _indexToTimer[partition.next()]; + } + } + + result += "]"; + return result; + //return _partition.toString(); + } + + /** + * Provides a lexigraphical ordering of the node according to the partition elements + * and internal edges. + */ + @Override + public int compareTo(Node o) { + + // Should be defined to be consistent with the equals property. + // Write so as to have early outs. + + // First check the partition. + Iterator thisValue = this._partition.iterator(); + Iterator otherValue = o._partition.iterator(); + + while(thisValue.hasNext() && otherValue.hasNext()){ + int currentThisValue = thisValue.next(); + int currentOtherValue = otherValue.next(); + + // If a value of the partition is different, then + // the comparison can be made already. + if(currentThisValue != currentOtherValue){ + return currentThisValue - currentOtherValue; + } + } + + // Making it here, means the partition are either equal + // or one is the subset of the other. So we check + // if one has remaining values. + if(otherValue.hasNext()){ + // This 'if' says that the other Node has more elements in its partition than + // the this Node. Consider the smaller partition as being smaller. + return -1; + } + else if(thisValue.hasNext()){ + // This 'if' says that this Node has more elements in its partition than + // the other Node. Consider the smaller partition as being smaller. + return 1; + } + + // Making it here means that the partitions contain the same elements. + // Now check the edges. + + Iterator thisWeight = this._internalEdges.iterator(); + Iterator otherWeight = o._internalEdges.iterator(); + + while(thisWeight.hasNext() && otherWeight.hasNext()){ + int currentThisWeight = thisWeight.next(); + int currentOtherWeight = otherWeight.next(); + + // If a value of the partition is different, then + // the comparison can be made already. + if(currentThisWeight != currentOtherWeight){ + return currentThisWeight - currentOtherWeight; + } + } + + // Making it here means that the edges are either the same, + // or one is a subset of the other. + + return this._internalEdges.size() - o._internalEdges.size(); + } + + + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object o) { + // Check if the reference is null. + if(o == null) + { + return false; + } + + // Check that the type is correct. + if(!(o instanceof Node)) + { + return false; + } + + // Check for equality using the Node equality. + return equals((Node) o); + } + + /** + * Tests for equality. + * @param otherGraph + * @return + */ + public boolean equals(Node otherNode){ + + // Check if the reference is null first. + if(otherNode == null) + { + return false; + } + + // Check for reference equality. + if(this == otherNode) + { + return true; + } + + // If the hash codes are different, then the objects are not equal. + if(this.hashCode() != otherNode.hashCode()) + { + return false; + } + + // Check if the partitions are the same. + if(this._partition.size() != otherNode._partition.size()){ + return false; + } + + + if(!this._partition.equals(otherNode._partition)){ + return false; + } + + if(this._internalEdges.size() != otherNode._internalEdges.size()){ + return false; + } + + for(int i=0; i=0){ + return _nodeHashCode; + } + + // Set the hash code. + _nodeHashCode = Math.abs(_partition.hashCode()^_internalEdges.hashCode()); + + return _nodeHashCode; + } + + } + + /** + * A directed edge of the graph. + * @author Andrew N. Fisher + * + */ + private class Edge{ + + /* + * Abstraction Function : + * + */ + + /* + * Representation Invariant : + * + */ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + getOuterType().hashCode(); + result = prime * result + + ((_terminal == null) ? 0 : _terminal.hashCode()); + result = prime * result + _weight; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Edge other = (Edge) obj; + return this.equals(other); + } + + public boolean equals(Edge other){ + if(this == other){ + return true; + } + + if(other == null){ + return false; + } + + if(this.hashCode() != other.hashCode()){ + return false; + } + + if (_terminal == null) { + if (other._terminal != null){ + return false; + } + } else if (!_terminal.equals(other._terminal)) + return false; + if (_weight != other._weight) + return false; + return true; + } + + /* + * Weight of edge. + */ + int _weight; + + /* + * Ending node. + */ + + Node _terminal; + + /** + * Creates an edge. + * @param initialNode + * The starting node for the edge. + * @param weight + * The weight of the edge. + * @param terminalNode + * The terminal node for the edge. + */ + public Edge(Node terminalNode, int weight){ + + _weight = weight; + _terminal = terminalNode; + } + + /** + * Get the weight associated with this Edge. + * @return + * The weight associated with this Edge. + */ + public int getWeight() { + + return _weight; + } + + public Node getTerminalNode() { + + return _terminal; + } + + /** + * Overrides Object's toString(). + */ + @Override + public String toString(){ + String s = ""; + + //s += "-" + _weight +"-> " + _terminal._name; + + s += "-" + _weight + "-> " + _terminal.partitionString(); + + return s; + } + + private ZoneGraph getOuterType() { + return ZoneGraph.this; + } + } + + private class intPair{ + + int _leftInt, _rightInt; + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + getOuterType().hashCode(); + result = prime * result + _leftInt; + result = prime * result + _rightInt; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + intPair other = (intPair) obj; + if (!getOuterType().equals(other.getOuterType())) + return false; + if (_leftInt != other._leftInt) + return false; + if (_rightInt != other._rightInt) + return false; + return true; + } + + public intPair(int leftInt, int rightInt) { + this._leftInt = leftInt; + this._rightInt = rightInt; + } + + public int getLeftInt() { + return _leftInt; + } + + @SuppressWarnings("unused") + public void setLeftInt(int leftInt) { + this._leftInt = leftInt; + } + + public int getRightInt() { + return _rightInt; + } + + @SuppressWarnings("unused") + public void setRightInt(int rightInt) { + this._rightInt = rightInt; + } + + private ZoneGraph getOuterType() { + return ZoneGraph.this; + } + + @Override + public String toString(){ + return "(" + this._leftInt + "," + this._rightInt + ")"; + } + } + + public static int getUpperBoundbyTransitionIndex(int timer) { + return 0; + } + + public static int getUpperBoundbydbmIndex(int index) { + return 0; + } + + public static int getLowerBoundbyTransitionIndex(int timer) { + return 0; + } + + public static int getLowerBoundbydbmIndex(int index) { + return 0; + } + + public static int getDbmEntry(int i, int j) { + return 0; + } + + public static boolean exceedsLowerBoundbyTransitionIndex(int timer) { + return false; + } + + public static boolean exceedsLowerBoundbydbmIndex(int index) { + return false; + } + + public static ZoneType fireTransitionbyTransitionIndex(int timer, + int[] enabledTimers, State state) { + return null; + } + + public static ZoneType fireTransitionbydbmIndex(int index, int[] enabledTimers, + State state) { + return null; + } + + public static List getEnabledTransitions() { + return null; + } + + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneGraphTest.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneGraphTest.java new file mode 100644 index 000000000..d7344f1b3 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneGraphTest.java @@ -0,0 +1,257 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zone; + +import static org.junit.Assert.*; + +import java.io.File; +import java.io.PrintStream; + +import org.junit.Before; +import org.junit.Test; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ZoneGraphTest { + + Zone zone1, zone2, zone3, zone4, zone5, zone6; + + public static int INF = ZoneType.INFINITY; + + @Before + public void setUp() throws Exception { + + int[] timers1 = new int[]{2, 3, 5}; + int[][] matrix1 = new int[][]{ + {0, 0, 0, 0, 0}, + {0, 0, 2, 2, 2}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0} + }; + + zone1 = new Zone(timers1, matrix1); + + int[] timers2 = new int[]{1, 2, 3}; + + int[][] matrix2 = new int[][]{ + {0, 0, 0, 0, 0}, + {0, 0, INF, INF, 5}, + {0, 3, 0, 10, 2}, + {0, INF, -4, 0, INF}, + {0, INF, INF, 2, 0} + }; + + zone2 = new Zone(timers2, matrix2); + + int[] timer3 = new int[]{0, 1, 6, 9}; + + int[][] matrix3 = new int[][]{ + {0, 0, 3, 2, 1, 6}, + {0, 0, 3, 0, 1, 1}, + {-2, -2, 0, -2, -1, -1}, + {-1, 0, 3, 0, 1, 1}, + {0, -1, 2, -1, 0, 0}, + {-5, -1, 2, -1, 0, 0} + }; + + zone3 = new Zone(timer3, matrix3); + + int[] timer4 = new int[]{1, 6, 9, 0}; + + int[][] matrix4 = new int[][]{ + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, INF, INF, 3}, + {0, INF, 0, 1, INF, INF}, + {0, INF, INF, 0, 0, INF}, + {0, -1, INF, INF, 0, INF}, + {0, -2, INF, INF, INF, 0} + }; + + zone4 = new Zone(timer4, matrix4); + + + // Set up fifth zone. + int[] timers5 = new int[]{1}; + int[][] matrix5 = new int[][]{ + {0, 0, 2}, + {0, 0, 2}, + {0, -2, 0} + }; + + zone5 = new Zone(timers5, matrix5); + + // Set up sixth zone. + int[] timers6 = new int[]{1, 2, 3, 4}; + int[][] matrix6 = new int[][]{ + { 0, 0, 2, 4, 6, 2}, + { 0, 0, 2, 2, 2, 2}, + {-1, 0, 0, 0, 0, 0}, + { 0, 0, 2, 0, 2, 0}, + {-5, 0, 0, 0, 0, 0}, + {-1, 0, 2, 0, 2, 0} + }; + + zone6 = new Zone(timers6, matrix6); + } + + @Test + public void testToDot1() { + try{ + PrintStream zone1DotFile = new PrintStream(new File("gui\\src\\verification" + + "\\timed_state_exploration\\zone\\zone1.dot")); + + PrintStream zoneGraphDotFile = new PrintStream(new File("gui\\src\\verification" + + "\\timed_state_exploration\\zone\\zoneGraph1.dot")); + + zone1.toDot(zone1DotFile); + + ZoneGraph g = ZoneGraph.extractZoneGraph(zone1); + + g.toDot(zoneGraphDotFile); + + Zone actual = g.extractZone(); + + assertTrue(zone1.equals(actual)); + } + catch(Exception e){ + e.printStackTrace(); + } + } + + @Test + public void testToDot2(){ + try{ + PrintStream zone1DotFile = new PrintStream(new File("gui\\src\\verification" + + "\\timed_state_exploration\\zone\\zone2.dot")); + + PrintStream zoneGraphDotFile = new PrintStream(new File("gui\\src\\verification" + + "\\timed_state_exploration\\zone\\zoneGraph2.dot")); + + zone2.toDot(zone1DotFile); + + ZoneGraph g = ZoneGraph.extractZoneGraph(zone2); + + g.toDot(zoneGraphDotFile); + + Zone actual = g.extractZone(); + + assertTrue(zone2.equals(actual)); + } + catch(Exception e){ + e.printStackTrace(); + } + } + + @Test + public void testToDot3(){ + try{ + PrintStream zone1DotFile = new PrintStream(new File("gui\\src\\verification" + + "\\timed_state_exploration\\zone\\zone3.dot")); + + PrintStream zoneGraphDotFile = new PrintStream(new File("gui\\src\\verification" + + "\\timed_state_exploration\\zone\\zoneGraph3.dot")); + + zone3.toDot(zone1DotFile); + + ZoneGraph g = ZoneGraph.extractZoneGraph(zone3); + + g.toDot(zoneGraphDotFile); + + Zone actual = g.extractZone(); + + assertTrue(zone3.equals(actual)); + } + catch(Exception e){ + e.printStackTrace(); + } + } + + @Test + public void testToDot5(){ + try{ + PrintStream zone1DotFile = new PrintStream(new File("gui\\src\\verification" + + "\\timed_state_exploration\\zone\\zone5.dot")); + + PrintStream zoneGraphDotFile = new PrintStream(new File("gui\\src\\verification" + + "\\timed_state_exploration\\zone\\zoneGraph5.dot")); + + zone5.toDot(zone1DotFile); + + ZoneGraph g = ZoneGraph.extractZoneGraph(zone5); + + g.toDot(zoneGraphDotFile); + + Zone actual = g.extractZone(); + + assertTrue(zone5.equals(actual)); + } + catch(Exception e){ + e.printStackTrace(); + } + } + + @Test + public void testToDot6(){ + try{ + PrintStream zone1DotFile = new PrintStream(new File("gui\\src\\verification" + + "\\timed_state_exploration\\zone\\zone6.dot")); + + PrintStream zoneGraphDotFile = new PrintStream(new File("gui\\src\\verification" + + "\\timed_state_exploration\\zone\\zoneGraph6.dot")); + + zone6.toDot(zone1DotFile); + + ZoneGraph g = ZoneGraph.extractZoneGraph(zone6); + + g.toDot(zoneGraphDotFile); + + Zone actual = g.extractZone(); + + assertTrue(zone6.equals(actual)); + } + catch(Exception e){ + e.printStackTrace(); + } + } + + @Test + public void testEquals1(){ + ZoneGraph z1a = ZoneGraph.extractZoneGraph(zone1); + ZoneGraph z1b = ZoneGraph.extractZoneGraph(zone1); + + assertTrue(z1a.equals(z1b)); + } + + @Test + public void testEquals2(){ + ZoneGraph z = ZoneGraph.extractZoneGraph(zone2); + + assertTrue(z.equals(z)); + } + + @Test + public void testEquals3(){ + ZoneGraph z3 = ZoneGraph.extractZoneGraph(zone3); + ZoneGraph z5 = ZoneGraph.extractZoneGraph(zone5); + + assertFalse(z3.equals(z5)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneTest.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneTest.java new file mode 100644 index 000000000..c4233d183 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneTest.java @@ -0,0 +1,271 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zone; + +import static org.junit.Assert.*; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Scanner; + +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ZoneTest { + + static Zone zone1, zone2, zone3, zone4, zone5; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + // Set up first Zone. + int [] timers1 = new int[]{7, 2, 6, 3}; + int[][] matrix1 = new int[6][6]; + matrix1[0] = new int[]{0, 0, 17, 12, 16, 13}; + matrix1[1] = new int[]{0, 0, 7, 2, 6, 3}; + matrix1[2] = new int[]{-7, 0, 0, 0, 0, 0}; + matrix1[3] = new int[]{-2, 0, 0, 0, 0, 0}; + matrix1[4] = new int[]{-6, 0, 0, 0, 0, 0}; + matrix1[5] = new int[]{-3, 0, 0, 0, 0, 0}; + + zone1 = new Zone(timers1, matrix1); + + // Set up second Zone. + int[] timers2 = new int[]{2, 3, 6, 7}; + int[][] matrix2 = new int[6][6]; + matrix2[0] = new int[]{0, 0, 12, 13, 16, 17}; + matrix2[1] = new int[]{0, 0, 7, 2, 6, 3}; + matrix2[2] = new int[]{-2, 0, 0, 0, 0, 0}; + matrix2[3] = new int[]{-3, 0, 0, 0, 0, 0}; + matrix2[4] = new int[]{-6, 0, 0, 0, 0, 0}; + matrix2[5] = new int[]{-7, 0, 0, 0, 0, 0}; + + zone2 = new Zone(timers2, matrix2); + + // Set up third Zone. + int[] timers3 = new int[]{2}; + int[][] matrix3 = new int[][]{ + { 0, 0, 3}, + { 0, 0, 3}, + {-1, 0, 0} + }; + + zone3 = new Zone(timers3, matrix3); + + // Set up fourth Zone. + int[] timers4 = new int[]{1}; + int[][] matrix4 = new int[][]{ + { 0, 0, 3}, + { 0, 0, 3}, + {-1, 0, 0} + }; + + zone4 = new Zone(timers4, matrix4); + + // Set up fifth zone. + int[] timers5 = new int[]{1, 2, 3}; + int[][] matrix5 = new int[][]{ + { 0, 0, 2, 3, ZoneType.INFINITY}, + { 0, 0, 2, 3, ZoneType.INFINITY}, + {-1, 0, 0, 0, 0}, + {-2, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0} + }; + + zone5 = new Zone(timers5, matrix5); + } + + @Test + public static void testInifinity() + { + int expected02 = 2; + int expected03 = 2; + int actual02 = zone5.getDbmEntry(0, 2); + int actual03 = zone5.getDbmEntry(0, 3); + + assertEquals(expected02, actual02); + assertEquals(expected03, actual03); + } + + @Test + public static void testHashCode() { + + assertEquals(zone1.hashCode(), zone2.hashCode()); + } + + @Test + public static void testZone() { + + assertTrue(zone1.equals(zone2)); + + } + + @Test + public static void testGetdbm() { + int expected = 2; + int actual = zone1.getDbmEntry(0, 1); + assertEquals(expected, actual); + } + + @Test + public static void testGetUpperBoundbyTransitionIndex() { + + int expected2 = 12; + int expected3 = 13; + int expected6 = 16; + int expected7 = 17; + int actual2 = zone1.getUpperBoundbyTransitionIndex(2); + int actual3 = zone1.getUpperBoundbyTransitionIndex(3); + int actual6 = zone1.getUpperBoundbyTransitionIndex(6); + int actual7 = zone1.getUpperBoundbyTransitionIndex(7); + + assertEquals(expected2, actual2); + assertEquals(expected3, actual3); + assertEquals(expected6, actual6); + assertEquals(expected7, actual7); + } + + @Test + public static void testGetUpperBoundbydbmIndex() { + + int expected2 = 12; + int expected3 = 13; + int expected6 = 16; + int expected7 = 17; + int actual2 = zone1.getUpperBoundbydbmIndex(1); + int actual3 = zone1.getUpperBoundbydbmIndex(2); + int actual6 = zone1.getUpperBoundbydbmIndex(3); + int actual7 = zone1.getUpperBoundbydbmIndex(4); + + assertEquals(expected2, actual2); + assertEquals(expected3, actual3); + assertEquals(expected6, actual6); + assertEquals(expected7, actual7); + } + + @Test + public static void testGetLowerBoundbyTransitionIndex() { + int expected2 = -2; + int expected3 = -3; + int expected6 = -6; + int expected7 = -7; + int actual2 = zone1.getLowerBoundbyTransitionIndex(2); + int actual3 = zone1.getLowerBoundbyTransitionIndex(3); + int actual6 = zone1.getLowerBoundbyTransitionIndex(6); + int actual7 = zone1.getLowerBoundbyTransitionIndex(7); + + assertEquals(expected2, actual2); + assertEquals(expected3, actual3); + assertEquals(expected6, actual6); + assertEquals(expected7, actual7); + } + + @Test + public static void testGetLowerBoundbydbmIndex() { + int expected2 = -2; + int expected3 = -3; + int expected6 = -6; + int expected7 = -7; + int actual2 = zone1.getLowerBoundbydbmIndex(1); + int actual3 = zone1.getLowerBoundbydbmIndex(2); + int actual6 = zone1.getLowerBoundbydbmIndex(3); + int actual7 = zone1.getLowerBoundbydbmIndex(4); + + assertEquals(expected2, actual2); + assertEquals(expected3, actual3); + assertEquals(expected6, actual6); + assertEquals(expected7, actual7); + } + + @Test + public static void testEqualsZone() { + assertFalse(zone3.equals(zone4)); + } + + @Test + public static void testMergeZone(){ + ZoneType z = zone1.mergeZones(zone2); + + System.out.println("Merging zones 1 and 2 :"); + System.out.println(z); + } + + @Test + public static void testMergeZone2(){ + ZoneType z = zone3.mergeZones(zone4); + + + System.out.println("Merging zones 3 and 4 :"); + System.out.println(z); + } + + @SuppressWarnings("unused") + @Test + public static void testMergeZone3(){ + boolean exceptionThrown = false; + + try{ + ZoneType z = zone3.mergeZones(zone1); + } + catch(Exception e) + { + exceptionThrown = true; + } + + assertTrue(exceptionThrown); + } + + /** + * Reads in zones for testing. + * @param zoneFile + * The file containing the test zones. + * @return + * An array of zones for testing. + * + */ + @SuppressWarnings("unused") + private static ZoneType[] readTestZones(File zoneFile) + { + try { + Scanner read = new Scanner(zoneFile); + + while(read.hasNextLine()) + { + String line = read.nextLine(); + line.trim(); + + if(line.equals("start")) + { + + } + } + + read.close(); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + System.err.print("File not found."); + } + + + return null; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneType.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneType.java new file mode 100644 index 000000000..c3bdfd843 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zone/ZoneType.java @@ -0,0 +1,213 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zone; + +import java.util.HashMap; +import java.util.List; + +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public abstract class ZoneType { + + /* Infinity is represented by the maximum integer value. */ + public static final int INFINITY = Integer.MAX_VALUE; + + /* + * Turns on and off subsets for the zones. + * True means subset will be considered. + * False means subsets will not be considered. + */ + private static boolean _subsetFlag = true; + + /** + * Gets the value of the subset flag. + * @return + * True if subsets are requested, false otherwise. + */ + public static boolean getSubsetFlag(){ + return _subsetFlag; + } + + /** + * Sets the value of the subset flag. + * @param useSubsets + * The value for the subset flag. Set to true if + * supersets are to be considered, false otherwise. + */ + public static void setSubsetFlag(boolean useSubsets){ + _subsetFlag = useSubsets; + } + + /* + * Turns on and off supersets for zones. + * True means that supersets will be considered. + * False means that supersets will not be considered. + */ + private static boolean _supersetFlag = true; + + /** + * Gets the value of the superset flag. + * @return + * True if supersets are to be considered, false otherwise. + */ + public static boolean getSupersetFlag(){ + return _supersetFlag; + } + + /** + * Sets the superset flag. + * @param useSupersets + * The value of the superset flag. Set to true if + * supersets are to be considered, false otherwise. + */ + public static void setSupersetFlag(boolean useSupersets){ + _supersetFlag = useSupersets; + } + + /** + * Get the value of the upper bound for the delay. + * @param timer + * The timer's index. + * @return + * The upper bound on the transitions delay. + */ + public abstract int getUpperBoundbyTransitionIndex(int timer); + + /** + * Get the value of the upper bound for the delay. + * @param index + * The timer's row/column of the DBM matrix. + * @return + * The upper bound on the transitions delay. + */ + public abstract int getUpperBoundbydbmIndex(int index); + + /** + * Get the value of the lower bound for the delay. + * @param timer + * The timer's index. + * @return + * The value of the lower bound. + */ + public abstract int getLowerBoundbyTransitionIndex(int timer); + + /** + * Get the value of the lower bound for the delay. + * @param index + * The timer's row/column of the DBM matrix. + * @return + * The value of the lower bound. + */ + public abstract int getLowerBoundbydbmIndex(int index); + + /** + * Retrieves an entry of the DBM using the DBM's addressing. + * @param i + * The row of the DBM. + * @param j + * The column of the DBM. + * @return + * The value of the (i, j) element of the DBM. + */ + public abstract int getDbmEntry(int i, int j); + + /** + * Determines if a timer has reached its lower bound. + * @param timer + * The timer's index. + * @return + * True if the timer has reached its lower bound, false otherwise. + */ + public abstract boolean exceedsLowerBoundbyTransitionIndex(int timer); + + /** + * Determines if a timer has reached its lower bound. + * @param index + * The timer's row/column of the DBM. + * @return + * True if the timer has reached its lower bound, false otherwise. + */ + public abstract boolean exceedsLowerBoundbydbmIndex(int index); + + /** + * Updates the Zone according to a transition firing. + * @param timer + * The index of the transition that fired. + * @return + * The updated Zone. + */ + public abstract ZoneType fireTransitionbyTransitionIndex(int timer, + int[] enabledTimers, State state); + + /** + * Updates the Zone according to the transition firing. + * @param index + * The index of the timer. + * @return + * The updated Zone. + */ + public abstract ZoneType fireTransitionbydbmIndex(int index, + int[] enabledTimers, State state); + + /** + * Overrides the clone method from Object. + */ + @Override + public abstract ZoneType clone(); + + /** + * The list of enabled timers. + * @return + * The list of all timers that have reached their lower bounds. + */ + public abstract List getEnabledTransitions(); + + /** + * Retrieve a lexicon that maps the internal numbers to the transition. + * @return + * The lexicon. + */ + public abstract HashMap getLexicon(); + + /** + * Determines if this zone is a subset of Zone otherZone. + * @param otherZone + * The zone to compare against. + * @return + * True if this is a subset of other; false otherwise. + */ + public abstract boolean subset(ZoneType otherZone); + + /** + * Determines if this zone is a superset of Zone otherZone. + * @param otherZone + * The zone to compare against. + * @return + * True if this is a subset of other; false otherwise. More specifically it + * gives the result of otherZone.subset(this). Thus it agrees with the subset method. + */ + public boolean superset(ZoneType otherZone){ + return otherZone.subset(this); + } + +} \ No newline at end of file diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/Conolse7_26_2012.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/Conolse7_26_2012.java new file mode 100644 index 000000000..f58dca9ca --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/Conolse7_26_2012.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + +import java.io.File; +import java.util.ArrayList; + +import edu.utah.ece.async.ibiosim.dataModels.util.GlobalConstants; +import edu.utah.ece.async.ibiosim.dataModels.util.exceptions.BioSimException; +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.project.Project; +import edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject.Zone; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Conolse7_26_2012 { + + /** + * Parameters are + * 'b' = no subsets + * 'p' = no supersets + * @param args + * @throws BioSimException + */ + public static void main(String[] args) throws BioSimException { + + String lpnFileDirectory = ""; + boolean subset = true; + boolean superset = true; + boolean rateOptimization = false; // rate optimization is off by default + boolean octagons = false; // Determines whether the method is zones or octagons. + boolean flags = false; + if(args.length > 3 || args.length == 0){ + System.out.println("Incorrect number of parameters"); + return; + } + else if (args.length == 1){ + lpnFileDirectory = args[0]; + } + else{ + String commands = args[0]; + lpnFileDirectory = args[1]; + flags = commands.contains("-"); + subset = !commands.contains("b") & flags; + superset = !commands.contains("p") & flags; + rateOptimization = commands.contains("r") & flags; + octagons = commands.contains("o") & flags; + System.out.println("Subset is : " + subset); + System.out.println("Superset is : " + superset); + System.out.println("Octagons is : " + octagons); + System.out.println("The input string was : " + commands); + System.out.println("The file directory was: " + lpnFileDirectory); + } + + File directory = new File(lpnFileDirectory); + + if(!directory.exists()){ + System.out.println("Directory does not exist!"); + return; + } + + if(!directory.isDirectory()){ + System.out.println("Must pass a directory"); + return; + } + + String[] lpnList = directory.list(); + + if(lpnList == null || lpnList.length == 0){ + System.out.println("Directory is emtpy!"); + return; + } + + LPN lpn = new LPN(); + + lpn.load(directory + GlobalConstants.separator + lpnList[0]); + Options.set_TimingLogFile(directory + GlobalConstants.separator + + lpnList[0] + ".tlog"); + + + + ArrayList selectedLPNs = new ArrayList(); + // Add the current LPN to the list. + selectedLPNs.add(lpn); + for (int i=1; i < lpnList.length; i++) { + String curLPNname = lpnList[i]; + LPN curLPN = new LPN(); + curLPN.load(directory + GlobalConstants.separator + curLPNname); + selectedLPNs.add(curLPN); + } + + + // Extract boolean variables from continuous variable inequalities. + for(int i=0; i + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + +import java.util.HashMap; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ContinuousRecordSet extends HashMap { + + /** + * + */ + private static final long serialVersionUID = -7357798608686001995L; + + + /** + * Adds an UpdateContinuous record. + * + * @param record The UpdateContinuous object to add. + * @return The previous record for the same continuous variable if it exists; null + * otherwise. + */ + public UpdateContinuous add(UpdateContinuous record){ + return super.put(record, record); + } + + /** + * Returns any record that has an underlying LPNTransitionPair. This is contained + * in the LPNContAndRate portion of the UpdateContinuous. + * @param ltpair + * @return + */ + public UpdateContinuous get(LPNContinuousPair lcpair){ + + return super.get(new UpdateContinuous(lcpair)); + } + + public boolean contains(LPNContinuousPair lcpair){ + return super.containsKey(new UpdateContinuous(lcpair)); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/ContinuousUtilities.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/ContinuousUtilities.java new file mode 100644 index 000000000..7a414da93 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/ContinuousUtilities.java @@ -0,0 +1,952 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + +import java.util.ArrayList; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Variable; +import edu.utah.ece.async.lema.verification.platu.platuLpn.DualHashMap; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.timed_state_exploration.octagon.Equivalence; + +/** + * This class is meant as a utilities package. It contains static methods for + * handling inequalities to separate some of the more complicated methods + * from the zone. + * + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class ContinuousUtilities { + + /* + * Abstraction Function : This class is merely a collection of static methods + * so there is no abstraction function. + */ + + + /* + * Representation Invariant : This class contains only static methods, + * so it should not contain state, that is have member fields, and + * should not be instantiated. + */ + + + /** + * Determines the maximum amount time can advance for a given continuous + * variable before an inequality must change truth value. + * Note: It is assumed that the inequality is of the form + * 'continuous variable' operator 'constant'. + * @param z + * The Zone containing the continuous variable. + * @param contVar + * The continuous variable whose upper bound on time will be determined. + * @param localStates + * The current state. + * @return + * The maximum that contVar can be set to before an inequality + * must change truth value. + */ + public static int maxAdvance(Equivalence z, LPNTransitionPair contVar, + State[] localStates){ + + /* + * This method first extracts the list of continuous variables + * that contain contVar. These inequalities are contained in + * the Variable, so the first this is to extract that Variable + * followed by extracting the list. + * + * Next the main work is done. The basic idea is to find how far + * the variable can be advanced without changing the truth value of + * inequality. This is accomplished by seeing which inequalities put a constraint + * on how far the variable can be advance, then taking the minimum of all + * these constraints. + * + * To determine whether the inequality does provide a constraint, the + * algorithm determines whether the entire range of the variable lies below + * the constant, lies above the constant, or contains the constant. The third + * case is referred to as the 'straddle' case. Then it is determined if there is + * a constraint by taking into account three things: the specifically inequality + * in question ('<', '>'), the rate of the variable, and the current truth value of + * the inequality. + * + * In each of these cases is structured as an if-else block. The order is as follows. + * + * The first bifurcation is whether the inequality is + * 'variable' < 'constant' or 'variable' > 'constant' ('<=' is treated + * in the same case as '<' and '>=' is treated in the same case as '>'). + * For simplicity I will write the first case as 'xa'. + * + * The next bifurcation is whether the current rate of the variable is + * is positive or negative. The zero case will be consider if control falls + * all the way through the method. I will refer to these cases as + * 'r>0', 'r<0' and 'r=0', respectively. + * + * The last bifurcation is whether the inequality is true or false. I + * will refer to this bifurcation as i=1 or i=0, for true and false, + * respectively. + * + * The method also checks for some types of inconsistencies To illustrate + * these checks, suppose I have the inequality x>3. The first check is + * illustrated by supposing that the inequality is marked 'false' by + * the state and that the lower bound on x is 5. This leads to an + * inconsistency since the lower bound being 5 means the inequality would + * have to be true. For the second type of check, I will consider again the + * situation where x>3. Further I will suppose that the lower bound is 1 + * and the upper bound is 5. This leads to an inconsistency since for + * part of the zone, the inequality is true and for the other part the + * inequality is false. + * + * For the following, let zu be the DBM(0, i) entry where i is the + * index of the continuous variable x. Also let zl be the DBM(i,0) entry + * where i is the index of the continuous variable x. Note that since + * the zone is warped, zu = (upper bound)/r and zl = -1*(lower bound)/r when + * r > 0. When r<0, the upper and lower bounds are swapped. Thus + * zu = (lower bound)/r and zl = -1*(upper bound)/r. + * + * Note : in the warped zone, raising the upper bound on a variable with + * r<0 corresponds to lowering the lower bound of the variable when the + * variable is not warped. + * + * x>a + * r > 0 + * i=1 + * if(zu < a/r){ + * zu < a/r implies (upper bound)/r < a/r. Thus + * upper bound < a. + * The inequality has been erroneously marked true since + * lower bound < upper bound < a. To match atacs let + * newMin = upper bound. + * It doesn't matter what I set this value to since + * this cas should never happen. in these cases, atacs + * tends to take the path of setting the value to what it + * is already. + * This case should not happen. + * } + * else if (-1 * zl > a/r){ + * Since zl = -1* lower bound this inequality implies + * lower bound > a. + * Since the lower bound is greater than the constant + * every value in the range of x is greater than the + * constant. With the rate positive, x will be able + * to continue to increase without the inequality changing. + * Thus the inequality puts no constraints on the variable + * and the upper bound can be anything (bigger than the lower + * bound of course). So the new minimum is + * newMin = INFINITY + * } + * else{ + * This is the straddle case. Since the upper bound of + * x is greater than a, it can be increase with out bound + * and the inequality would still be true (as far as the + * portion of the Zone above a is concerned). The upper + * bound is still unconstrained, so set the minimum to + * newMin = INFINITY. + * } + * + * i=0 + * if(zu < a/r){ + * zu < a/r implies that + * upper bound < a. + * Again, lower bound < upper bound < a. So the values + * of x match marking the inequality as false. the + * value of x can then continue to increase until it + * reaches the constant. Thus the new minimum is + * newMin = a/r + * } + * else if (-1 * zl > a/r){ + * Since zl = -1*lower bound this inequality implies + * lower bound > a. + * In this case, a < lower bound < upper bound. Thus + * the inequality is true but has been erroneously marked + * false. Again, the upper bound is larger than it should + * be since the inequality is false. So the variable should not + * be allowed to advance further than it has. So set the minimum to + * newMin = zu. + * This case should not happen. + * } + * else{ + * This is again the straddle case. Since the inequality + * is false, the variable should not be allowed to advance + * any further. In this case atacs sets the value to + * newMin = zu. + * } + * + * r<0 (Note these are warped space below here.) + * i=1 + * if(zl < -1 * a/r){ + * OK, in this case x > a, x is decreasing, and + * the inequality is true. Further more recall that zl = -1*(upper bound)/r. + * So we have -1*(upper bound)/r < -1 * a/r which implies + * upper bound < a. + * So the inequality should be false and it isn't. We set the variables to it's + * current (warped) upper bound to stop it from advancing. So the new minimum is + * newMin = zu. + * This case should not happen. + * } + * else if(-1*zu > -1 *a/r){ + * Since zu = (lower bound)/r, the inequality becomes + * lower bound > a. + * Thus the entire range of the variable is above a and since x is decreasing, x + * is constrained by a. Thus set the new minimum to the (warped version) of a. + * newMin = a/r + * } + * else{ + * This is again the straddle case and the new minimum is set to the current largest + * value to stop the variable from advancing. So + * newMin = zu. + * } + * i=0 + * if(zl < -1 * a/r){ + * Since r<0, zl = -1*(upper bound)/r. The inequality thus become + * -1*(upper bound)/r < -1*a/r which implies + * upper bound < a. + * The entire range of x lies below the inequality since + * lower bound < upper bound < a. Since the variable is + * decreasing, it is unconstrained. The new minimum is then + * newMin = INFINITY. + * } + * else if (-1*zu > -1*a/r){ + * Since r<0, zu = (lower bound)/r, the inequality becomes + * lower bound > a. + * Thus the entire range of the variable is above a. This + * means the inequality is true and has been erroneously + * marked false so let's not let it advance any further. + * newMin = zu. + * } + * else{ + * This is the straddle case. Since decreasing the variable does + * not change the inequality, the variable is left unconstrained. + * So set + * newMin = INFINITY; + * } + * x0 + * i=1 + * if(zu < a/r){ + * Since zu = upper bound /r, the inequality is becomes + * upper bound < a. + * Thus the whole range of x is less than a, which is consistent with the + * x a/r){ + * Since zl = -1 * (lower bound)/r, the inequality becomes + * lower bound > a. + * Thus the entire range of x is above a which implies x a/r){ + * Since zl = -1* lower bound, the inequality is + * lower bound > a. + * Thus the entire range lies above the constant. The inequality x -1*a/r){ + * When the rate is negative, zu=(lower bound)/r. Thus the + * inequality becomes -1*(lower bound)/r > -1*a/r or + * lower bound > a. + * So the entire range is greater than the constant. But + * then the inequality is false and has been erroneously + * marked 'true'. The value has already advanced too far. + * newMin = zu. + * This case should not happen. + * } + * else{ + * This is the straddle case. Letting the inequality continue to + * decrease does not change the sign of the inequality, so + * we do not constrain the variable. Thus set the new minimum to + * newMin = INFINITY. + * } + * i=0 + * if(zl < -1 * a/r){ + * Again when the rate is negative, zl=-1*(upper bound)/r. + * So the inequality becomes -1*(upper bound)/r < -1 a/r or + * upper bound < a. + * So the entire range of the variable is below 'a' which + * makes the inequality true; however, it has been + * erroneously marked false. So freeze the variable at + * its current largest value + * newMin = zu. + * This case should not happen. + * } + * else if(-1*zu > -1 * a/r){ + * When the rate is negative, zu = (lower bound)/r. The + * inequality then becomes -1*(lower bound)/r > -1 * a/r or + * lower bound > a. + * So the entire range of the continuous variable is + * above the constant 'a'. Thus the variable can decrease + * until it reaches the constant. When we divide by the + * a negative rate, this corresponds to increasing to + * a/r. Thus the new minimum value is + * newMin = a/r. + * } + * else{ + * This is the final straddle case. Since the variable decreasing + * changes the sign the variable, the inequality constrains the variable. + * So freeze the variable at + * newMin = zu. + * } + */ + + + // Get the continuous variable in question. + int lpnIndex = contVar.get_lpnIndex(); + int varIndex = contVar.get_transitionIndex(); + + Variable variable = z.get_lpnList()[lpnIndex].getContVar(varIndex); + + // Get the zone index of the continuous variable. + int contDBMIndex = z.timerIndexToDBMIndex(contVar); + + // Initially set the value time to advance at INFINITY. This will + // be lowered if any inequalities force a lower value. + int min = Zone.INFINITY; + int newMin = Zone.INFINITY; + + // Get all the inequalities that reference the variable of interest. + ArrayList inequalities = variable.getInequalities(); + + if(inequalities == null){ + return Zone.INFINITY; + } + + for(InequalityVariable ineq : inequalities){ + + // Update the inequality variable. + //int ineqValue = ineq.evaluate(localStates[varIndex], z); + + // Get the current value of the inequality. + int ineqValue = localStates[ineq.get_lpn().getLpnIndex()].getCurrentValue(ineq.get_index()); + + + /* Working on a > or >= ineq */ + if(ineq.get_op().equals(">") || ineq.get_op().equals(">=")){ + + // If the rate is positive. + if(z.getCurrentRate(contVar) > 0){ + + // If the inequality is marked true. + if(ineqValue != 0){ + + // Check if the entire range lies below the constant. + //*if(z.getDbmEntry(0, contDBMIndex) + if(z.getUpperBoundTrue(contDBMIndex) + < chkDiv(ineq.getConstant(), z.getCurrentRate(contVar), false)){ +// newMin = z.getDbmEntry(0, contVar.get_transitionIndex()); + //*newMin = z.getDbmEntry(0, contDBMIndex); + newMin = z.getUpperBoundTrue(contDBMIndex); + System.err.println("maxAdvance: Impossible case 1."); + } + + // Check if the entire range lies above the constant. + //*else if ((-1)*z.getDbmEntry(contDBMIndex,0) + else if ((-1)*z.getLowerBoundTrue(contDBMIndex) + > chkDiv(ineq.getConstant(), + z.getCurrentRate(contVar), false)){ + + newMin = Zone.INFINITY; + + } + + else{ + // Straddle case + newMin = Zone.INFINITY; + } + } + else{ + // The inequality is marked false. + + // Check if the entire range lies below the constant. + //*if(z.getDbmEntry(0, contDBMIndex) + if(z.getUpperBoundTrue(contDBMIndex) + < chkDiv(ineq.getConstant(), z.getCurrentRate(contVar), false)){ + + newMin = chkDiv(ineq.getConstant(), + z.getCurrentRate(contVar), false); + } + + // Check if the entire range lies above the constant. + //*else if((-1)*z.getDbmEntry(contDBMIndex, 0) + else if((-1)*z.getLowerBoundTrue(contDBMIndex) + > chkDiv(ineq.getConstant(), z.getCurrentRate(contVar), false)){ + +// newMin = z.getDbmEntry(0, contVar.get_transitionIndex()); + //*newMin = z.getDbmEntry(0, contDBMIndex); + newMin = z.getUpperBoundTrue(contDBMIndex); + System.err.print("maxAdvance : Impossible case 3."); + } + + else{ + // straddle case + //*newMin = z.getDbmEntry(0,contDBMIndex); + newMin = z.getUpperBoundTrue(contDBMIndex); + } + } + } + + else{ + // The rate is negative. + // warp <= 0. + + if( ineqValue != 0){ + // The inequality is marked true. + + // Check if the entire range lies below the constant. + //*if(z.getDbmEntry(contDBMIndex,0) + if(z.getLowerBoundTrue(contDBMIndex) + < (-1)*chkDiv(ineq.getConstant(), + z.getCurrentRate(contVar), false)){ + + //*newMin = z.getDbmEntry(0,contDBMIndex); + newMin = z.getUpperBoundTrue(contDBMIndex); + System.err.println("Warning: my impossible case 2."); + } + + // Check if the entire range lies above the constant. + //*else if((-1)*z.getDbmEntry(0, contDBMIndex) + else if((-1)*z.getUpperBoundTrue(contDBMIndex) + > (-1)*chkDiv(ineq.getConstant(), + z.getCurrentRate(contVar), false)){ + + newMin = chkDiv(ineq.getConstant(), + z.getCurrentRate(contVar), false); +// System.err.println("Warning: impossible case 8a found."); + } + + else{ + // straddle case +// newMin = z.getDbmEntry(0, contVar.get_transitionIndex()); + //*newMin = z.getDbmEntry(0, contDBMIndex); + newMin = z.getUpperBoundTrue(contDBMIndex); + } + + } + + else{ + // The inequality is marked false. + + // Check if the entire range lies below the constant. + //*if(z.getDbmEntry(contDBMIndex,0) + if(z.getLowerBoundTrue(contDBMIndex) + < (-1)*chkDiv(ineq.getConstant(), + z.getCurrentRate(contVar), false)){ + + newMin = Zone.INFINITY; + } + + // Check if the entire range lies above the constant. + //*else if((-1)*z.getDbmEntry(0, contDBMIndex) + else if((-1)*z.getUpperBoundTrue(contDBMIndex) + > (-1)*chkDiv(ineq.getConstant(), + z.getCurrentRate(contVar), false)){ + + //*newMin = z.getDbmEntry(0,contDBMIndex); + //int tmp = z.getUpperBoundTrue(contDBMIndex); + + newMin = z.getUpperBoundTrue(contDBMIndex); + System.err.println("maxAdvance : Impossible case 4."); + } + + else{ + // straddle case + newMin = Zone.INFINITY; + } + } + } + } + + else{ + // Working on a < or <= ineq + + // Check if the rate is positive. + //if(z.getUpperBoundForRate(contVar) > 0){ + if(z.getCurrentRate(contVar) > 0){ + + if(ineqValue != 0){ + // The inequality is marked true. + + // Check if the entire range lies below the constant. + //*if(z.getDbmEntry(0, contDBMIndex) + if(z.getUpperBoundTrue(contDBMIndex) + < chkDiv(ineq.getConstant(), + z.getCurrentRate(contVar), false)){ + + newMin = chkDiv(ineq.getConstant(), + z.getCurrentRate(contVar), false); + } + + // Check if the entire range lies above the constant. + //*else if((-1)*z.getDbmEntry(contDBMIndex, 0) + else if((-1)*z.getLowerBoundTrue(contDBMIndex) + > chkDiv(ineq.getConstant(), z.getCurrentRate(contVar),false)){ + + newMin = Zone.INFINITY; + System.err.println("Warning : Impossible case 5."); + } + + else{ + //straddle case + //*newMin = z.getDbmEntry(0,contDBMIndex); + newMin = z.getUpperBoundTrue(contDBMIndex); + } + + } + + else{ + // The inequality is marked false. + + // Check if the entire range lies below the constant. + //*if(z.getDbmEntry(0, contDBMIndex) + if(z.getUpperBoundTrue(contDBMIndex) + < chkDiv(ineq.getConstant(), + z.getCurrentRate(contVar), false)){ + +// newMin = z.getDbmEntry(0, contVar.get_transitionIndex()); + //*newMin = z.getDbmEntry(0, contDBMIndex); + newMin = z.getUpperBoundTrue(contDBMIndex); + System.err.println("maxAdvance : Impossible case 7."); + } + + // Check if the entire range lies above the constant. + //*else if((-1)*z.getDbmEntry(contDBMIndex, 0) + else if((-1)*z.getLowerBoundTrue(contDBMIndex) + > chkDiv(ineq.getConstant(), + z.getCurrentRate(contVar), false)){ + + newMin = Zone.INFINITY; +// System.err.println("Warning: impossible case 8a found."); + } + + else{ + // straddle case + + newMin = Zone.INFINITY; + } + } + + } + + else { + // The rate is negative. + // warp <=0 + + if(ineqValue != 0){ + // The inequality is marked true. + + // Check if the entire range lies below the constant. + //*if(z.getDbmEntry(contDBMIndex, 0) + if(z.getLowerBoundTrue(contDBMIndex) + < (-1)*chkDiv(ineq.getConstant(), + z.getCurrentRate(contVar), false)){ + + newMin = Zone.INFINITY; + } + + // Check if the entire range lies above the constant. + //*else if((-1)*z.getDbmEntry(0, contDBMIndex) + else if ((-1)*z.getUpperBoundTrue(contDBMIndex) + > (-1)*chkDiv(ineq.getConstant(), + z.getCurrentRate(contVar), false)){ + + //*newMin = z.getDbmEntry(0, contDBMIndex); + newMin = z.getUpperBoundTrue(contDBMIndex); + System.err.println("Warning : Impossible case 8."); + } + + + else { + // straddle case + newMin = Zone.INFINITY; + } + + } + + + else { + // The inequality is marked false. + + // Check if the entire range lies below the constant. + //*if(z.getDbmEntry(contDBMIndex,0) + if(z.getLowerBoundTrue(contDBMIndex) + < chkDiv((-1)*ineq.getConstant(), + z.getCurrentRate(contVar), false)){ + + //*newMin = z.getDbmEntry(0,contDBMIndex); + newMin = z.getUpperBoundTrue(contDBMIndex); + System.err.println("Warning : Impossible case 6"); + } + + // Check if the entire range lies above the constant. + //*else if((-1)*z.getDbmEntry(0,contDBMIndex) + else if((-1)*z.getUpperBoundTrue(contDBMIndex) + > (-1)*chkDiv(ineq.getConstant(), + (-1)*z.getCurrentRate(contVar),false)){ + + newMin = chkDiv(ineq.getConstant(), z.getCurrentRate(contVar),false); + } + + + + else { + // straddle case + +// newMin = z.getDbmEntry(0, contVar.get_transitionIndex()); + //*newMin = z.getDbmEntry(0, contDBMIndex); + newMin = z.getUpperBoundTrue(contDBMIndex); + } + + + } + } + } + // Check if the value can be lowered. + if(newMin < min){ + min = newMin; + } + } + + + return min; + } + + /** + * Determines whether time has advanced far enough for an inequality to change + * truth value. + * @param ineq + * The inequality to test whether its truth value can change. + * @param localState + * The state associated with the inequality. + * @return + * True if the inequality can change truth value, false otherwise. + */ + public static boolean inequalityCanChange(Equivalence z, InequalityVariable ineq, State localState){ + + /* + * The Inequality is assumed to be of the form + * (expression with variable) inequality (expression evaluating to constant). + * Let the inequality be expression as x>a or x' and '>=' is considered the same as '>'.) + * An inequality can change sign in four ways. One way for both positive + * and negative rates for each type of inequality x>a and x 0. When r<0, the upper and lower bounds are swapped. Thus + * zu = (lower bound)/r and zl = -1*(upper bound)/r. + * + * + * x > a + * r < 0 + * if(-1* zu < -1*a/r && inequality true){ + * This case covers the situation where the variable x + * starts above the constant and decreases until it crosses + * the constant turnin the inequality from true to false. + * Since zu = -1*(lower bound)/r, the inequality becomes + * -1*(lower bound)/r < -1*a/r or + * lower bound < a. + * Since the lower bound exceeds the constant, the inequality + * can change. + * } + * r > 0 + * if(zu > a/r && inequality false){ + * This is the case where the variable x is below the constant + * and the variable then exceeds the constant. + * Since zu = (upper bound)/r the inequality becomes + * upper bound > a. + * Since the upper bound exceeds the constant, the inequality + * can change. + * } + * x < a + * r < 0 + * if(-1*zu < -1*a/r && inequality false){ + * This case again has the variable x above is again above the + * constant 'a' and is going to cross it, but this time the + * the inequality becomes true when it was false. + * Since zu = -1*(lower bound)/r, the inequality becomes + * -1*(lower bound)/r < -1*a/r or + * lower bound < a. + * Since the lower bound exceeds the constant, the inequality + * can change. + * } + * r > 0 + * if(zu > a/r && inequality true){ + * This case has the variable x below the constant and the + * variable reaches the point where it will exceed the constant + * thus turing the truth value of the inequality from + * true to false. + * Since zu = (upper bound)/r the inequality becomes + * upper bound > a. + * Since the upper bound exceeds the constant, the inequality + * can change. + * } + */ + + // Find the index of the continuous variable this inequality refers to. + // I'm assuming there is a single variable. + LPN lpn = ineq.get_lpn(); + Variable contVar = ineq.getContVariables().get(0); + DualHashMap variableIndecies = lpn.getContinuousIndexMap(); + int contIndex = variableIndecies.getValue(contVar.getName()); + + // Package up the information into a the index. Note the current rate doesn't matter. + LPNContinuousPair index = new LPNContinuousPair(lpn.getLpnIndex(), contIndex, 0); + + // Get the current rate. + int currentRate = z.getCurrentRate(index); + + // Get the current value of the inequality. This requires looking into the current state. + int currentValue = localState.getCurrentValue(ineq.getName()); + + // Get the Zone index of the variable. + int zoneIndex = z.timerIndexToDBMIndex(index); + + // > or >= + if(ineq.get_op().contains(">")){ + + // First checking cases when the rate is negative. + if(currentRate < 0 && currentValue != 0){ + + // Inequality is x>a. This is the case + // x lies above the and decreases below it making + // the inequality turn from true to false. + //if((-1) * z.getDbmEntry(0, zoneIndex) <= + if((-1)*z.getUpperBoundTrue(zoneIndex) <= + (-1)*chkDiv(ineq.getConstant(), currentRate, false)){ + return true; + } + return false; + } + + // Inequality is x>a. This is the case + // x lies below the constant and rises until it exceeds + // the constant thus causing the inequality to go from + // false to true. + else if(currentRate > 0 && currentValue == 0){ + //if(z.getDbmEntry(0, zoneIndex) >= + if(z.getUpperBoundTrue(zoneIndex) >= + chkDiv(ineq.getConstant(), currentRate, false)){ + return true; + } + return false; + } + } + /* < or <= */ + else if(ineq.get_op().contains("<")){ + + // Inequality is x 0 && + currentValue != 0){ + //if(z.getDbmEntry(0, zoneIndex) >= + if(z.getUpperBoundTrue(zoneIndex) >= + chkDiv(ineq.getConstant(), currentRate, false)){ + return true; + } + return false; + } + + else { + return false; + } + } + return false; + } + + /** + * Performs a division of two integers and either takes the ceiling or the floor. Note : + * The integers are converted to doubles for the division so the choice of ceiling or floor is + * meaningful. + * @param top + * The numerator. + * @param bottom + * The denominator. + * @param ceil + * True indicates return the ceiling and false indicates return the floor. + * @return + * Returns the ceiling of top/bottom if ceil is true and the floor of top/bottom otherwise. + */ + public static int chkDiv(int top, int bottom, Boolean ceil){ + /* + * This method was taken from atacs/src/hpnrsg.c + */ + int res = 0; + if(top == Zone.INFINITY || + top == Zone.INFINITY * -1) { + if(bottom < 0) { + return top * -1; + } + return top; + } + if(bottom == Zone.INFINITY) { + return 0; + } + if(bottom == 0) { + System.out.println("Warning: Divided by zero."); + bottom = 1; + } + + double Dres,Dtop,Dbottom; + Dtop = top; + Dbottom = bottom; + Dres = Dtop/Dbottom; + if(ceil) { + res = (int)Math.ceil(Dres); + } + else if(!ceil) { + res = (int)Math.floor(Dres); + } + return res; + } + + /** + * Updates the inequalities variables in the state. Note : this + * method will change the current state. + * @param z + * The zone containing information about the current continuous + * variables. + * @param s + * The state to update the inequalities in. + */ + //*public static void updateInitialInequalities(Zone z, State s){ + public static void updateInitialInequalities(Equivalence z, State s){ + // Extract the LPN. + LPN lpn = s.getLpn(); + + // Get the state vector to update. +// int[] vector = s.getVector(); + + // The variables are not stored in the state, so get them from the LPN. + String[] variables = lpn.getVariables(); + + // Find the inequality variables. + for(int i=0; i + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + +import edu.utah.ece.async.lema.verification.lpn.Transition; + +/** + * An Event is an action that is pending. This can be a transition to fire or an inequality. + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Event { + + /* + * Abstraction Function : An event simply represents a transition, an Inequality, + * or a rate change. Whichever the event is representing is stored in the + * corresponding member variables _transition, _inequality, or _rate. + */ + + /* + * Representation Invariant : Exactly one of _transition, _inequality, or _rate + * should be non-null at a given time. + */ + + private Transition _transition; + + private InequalityVariable _inequality; + + // The rate stored as the currentRate is the rate the variable is going to be + // changed to. + private LPNContinuousPair _rate; + + /** + * Initializes the Event as a transition event. + * @param t + * The transition the event represents. + */ + public Event(Transition t){ + _transition = t; + } + + /** + * Initializes the Event as an inequality event. + * @param v + * The inequality this event represents. + */ + public Event(InequalityVariable v){ + _inequality = v; + } + + /** + * Initializes the Even as a rate change event. + * @param r + */ + public Event(LPNContinuousPair r){ + _rate = r; + } + + /** + * Determines whether this Event represents a Transition. + * @return + * True if this EventSet represents a Transition; false otherwise. + */ + public boolean isTransition() { + + return _transition != null; + } + + + /** + * Determines whether this Event represents a rate event. + * @return + * True if this EventSet represents a rate event; false otherwise. + */ + public boolean isRate() { + + return _rate != null; + } + + /** + * Determines whether this Event represents an inequality. + * @return + * True if this Event is an inequality, false otherwise. + */ + public boolean isInequality(){ + return _inequality != null; + } + + /** + * Gets the inequality variable that this Event represents. + * @return + * The inequality variable if this Event represents an inequality, null otherwise. + */ + public InequalityVariable getInequalityVariable(){ + return _inequality; + } + + /** + * Gets the transition that this Event represents. + * @return + * The transition if this Event represents a transition, null otherwise. + */ + public Transition getTransition(){ + return _transition; + } + + /** + * Gets the rate change for the rate change event this Event represents. + * @return + */ + public LPNContinuousPair getRateChange(){ + return _rate; + } + + /* + * (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString(){ + String result = ""; + + // Test if this event is a transition or is an inequality. + if(_transition != null){ + // This event represents a transition. + result += "Transition Event : " + _transition.getLabel(); + } + else if(_inequality != null){ + // This event represents an inequality. + result += "Inequality Event : " + _inequality; + } + else if(_rate != null){ + // This event represents a rate change. + result += "Rate change Event: " + _rate; + } + else{ + // The event is not initialized. + result += "Event not initialized"; + } + return result; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/EventSet.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/EventSet.java new file mode 100644 index 000000000..67e38c917 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/EventSet.java @@ -0,0 +1,663 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.NoSuchElementException; + +import edu.utah.ece.async.lema.verification.lpn.Transition; + +/** + * An EventSet represents a transition to fire, a set of inequalities that must + * fire together, or a rate change. When the EventSet represents a single transition, + * it is said to be in Transition mode. When the EventSet represents a list of + * inequalities, it is said to be in Inequality mode. When it represents a rate + * rate change it is said to be in Rate mode. + * + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class EventSet extends Transition implements Iterable{ + + /* + * Abstraction Function : An EventSet is a singleton set containing a Transition, + * a set of IneqaulityVariables, or a singleton set representing a rate change. + * Accordingly, an EventSet is said to operate in one + * of three modes: a Transition mode, an Inequality mode, or a Rate mode. When the + * EventSet contains no elements it is said to have No Mode. When the EventSet + * contains a single Transition it is stored as the _transition variable. When + * the EventSet contains a set InequalityVariables, they are stored in + * _inequalities. When the EventSet contains a rate change, the variable and new + * rate are stored as an LPNContinuousPair in the _rate variable. + */ + + + /* + * Representation Invariant : + * Exactly one of the fields '_transition', '_inequalities', '_rate' should be + * non-null. Testing for null is how this class determines whether it represents + * a Transition, a set of inequalities, or a rate change. All three variables can + * be null in which case the EventSet can be changed to either mode by storing + * something in the _transition, _inequalities or rate variables. + */ + + // A variable indicating whether we are a transition or a set of inequalities + // may not be need since we could test for null or non-null. + // Indicates whether this EventSet is a transitions or a set of inequalities. +// boolean _isTransition; + + + // The transition to fire. + Transition _transition; + + // The set of inequalities. + ArrayList _inequalities; + + // The rate to change. + LPNContinuousPair _rate; + + // Cached hash code value. +// int _hashCode; + + /** + * Overrides the hashCode. + */ +// @Override +// public int hashCode() +// { +// // Check if the hash code has been set. +// if(_hashCode <0) +// { +// _hashCode = createHashCode(); +// } +// +// return _hashCode; +// } + + /** + * Creates a hash code for an EventSet object. + * @return + * The hash code. + */ +// private int createHashCode() +// { +// int newHashCode = 37; +// +// if(!(_transition == null)){ +// newHashCode ^= _transition.hashCode(); +// } +// +// if(!(_inequalities == null)){ +// for(InequalityVariable ineq : _inequalities){ +// newHashCode ^= ineq.hashCode(); +// } +// } +// +// if(!(_rate == null)){ +// newHashCode ^= _rate.hashCode(); +// } +// +// return Math.abs(newHashCode); +// } + + /** + * Creates an uninitialized EventSet. The mode of the EventSet is determined by the first use + * of the insert method. If a Transition event is added, then the EventSet will be in the Transition mode. + * If an inequality event is added, then the EventSet will be in the Inequality mode. + */ + public EventSet(){ + // The mode will be determined by the first element added into the EventSet. + } + + /** + * Creates an EventSet in the Transition mode. + * @param transition + * The transition the EventSet should contain. + */ + public EventSet(Transition transition){ + _transition = transition; + } + + /** + * Creates an EventSet in the Inequality mode. + * @param inequalities + * The list of inequalities that the EventSet should contain. + */ + public EventSet(Collection inequalities){ + _inequalities = new ArrayList(); + _inequalities.addAll(_inequalities); + } + + /** + * Creates an EventSet in the Rate mod. + * @param rate + */ + public EventSet(LPNContinuousPair rate){ + _rate = rate; + } + + /** + * Determines whether this EventSet represents a Transition. + * @return + * True if this EventSet represents a Transition; false otherwise. + */ + public boolean isTransition(){ + return _transition != null; + } + + /** + * Determines whether this EventSet represents a set of Inequalities. + * @return + * True if this EventSet represents a set of inequalities; false otherwise. + */ + public boolean isInequalities(){ + return _inequalities != null; + } + + /** + * Determines whether the EventSet represents a rate event. + * @return + * True if this EventSet represents a rate event; false otherwise. + */ + public boolean isRate(){ + return _rate != null; + } + + /** + * Inserts an inequality event into the set of IneqaulityVariables when the EventSet is in + * the Inequality mode. + * @param e + * + * @throws IllegalArgumentException + * Throws an IllegalArgumentException if in the Inequality mode and e + * is not an inequality event or if the EventSet is in the Transition mode. + */ + public void add(Event e){ + // Determine if the mode is the Inequality mode + if(_inequalities != null){ + // We are in the inequality mode, now determine if the Event passed + // is and inequality. + if(e.isInequality()){ + // It is an inequality, so add it. + _inequalities.add(e.getInequalityVariable()); + } + else{ + // Tried to insert something other than an inequality into an + // inequality list, so complain. + throw new IllegalArgumentException("Cannot insert a non-inequality" + + " into an EventSet of inequalities."); + } + return; + } + + // We are not in the Inequality mode. + // If we are also not in the Transition mode or Rate mode, then the new + //event determines the mode. + if(_transition == null || _rate == null){ + if(e.isInequality()){ + // The event is an inequality, so add it to the inequalities. + // This also implies that the mode is the Inequality mode. + _inequalities = new ArrayList(); + _inequalities.add(e.getInequalityVariable()); + } + else if(e.isTransition()){ + // The event is a Transition, so store it. This also implies the + // mode is the Transition mode. + _transition = e.getTransition(); + } + else{ + // Since the event is not an inequality or a transition, it must + // for a rate change. + _rate = e.getRateChange(); + } + + return; + } + + // We are in the Transition mode or Rate mode. Nothing can be added in the + // these modes so yell. + throw new IllegalArgumentException("Another event was attempted to be added" + + "to an EventSet that already had a transition or rate in it."); + } + + /** + * Returns an iterator that returns the elements in the set as Event objects. + */ + @Override + public Iterator iterator(){ + return new EventSetIterator(); + } + + /** + * Clones the EventSet. Copies the internal objects by copying their reference. It does not make new instances + * of the contained objects. + */ + @Override + public EventSet clone(){ + + // Create a new EventSet instance. + EventSet newSet = new EventSet(); + + // Determine whether or not the EventSet is in the Inequality mode. + if(_inequalities != null){ + // In the Inequality mode, we need to make a new ArrayList and copy the elements references over. + newSet._inequalities = new ArrayList(); + newSet._inequalities.addAll(this._inequalities); + } + + else if (_transition != null){ + // In this case we are in the Transition mode. Simple copy the transition over. + newSet._transition = this._transition; + } + else{ + // Since we are not in Inequality or Transition mode, we must be in Rate + // mode (or have no mode). Simply copy the rate. + newSet._rate = this._rate; + } + + return newSet; + } + + /** + * Removes an element from the EventSet. + * @param e + * The event to remove. + */ + public void remove(Event e){ + // If the event is a transition and is equal to the stored transition + // remove the stored transition. + if(e.isTransition() && e.equals(_transition)){ + _transition = null; + return; + } + + // If the event is a rate change and is equal to the stored rate change, + // remove the stored rate. + if(e.isRate() && e.equals(_rate)){ + _rate = null; + return; + } + + // If the event is an inequality and the EventSet contains inequalities, + // attempt to remove the event. + if(_inequalities != null && e.isInequality()){ + _inequalities.remove(e.getInequalityVariable()); + } + } + + /** + * Determines the number of elements in the EventSet. + * @return + * The number of elements in the EventSet. + */ + public int size(){ + if(_transition != null || _rate != null){ + // If we are in the Transition mode or Rate mode, the size is 1. + return 1; + } + // If we are in the Inequality mode, the size is the + // number of inequalities. + return _inequalities.size(); + } + + /** + * Determines whether any elements are in the set. + * @return + * True if there is a least one element, false otherwise. + */ + public boolean isEmpty(){ + + // If one of the member variables is not null (and contains elements), + // the set is not empty. + if(_transition != null || _rate != null || + (_inequalities != null && _inequalities.size() != 0)){ + return false; + } + return true; + } + + /** + * Retrieve the transition that this EventSet represents. + * @return + * The transition that this EventSet represents or null if + * this EventSet does not represent a transition. + */ + public Transition getTransition(){ + return _transition; + } + + /** + * Retrieve the rate change that this EventSet represents. + * @return + * The rate change that this EventSet represents or null if + * this EventSet does not represent a rate change. + */ + public LPNContinuousPair getRateChange(){ + return _rate; + } + + /* + * (non-Javadoc) + * @see lpn.parser.Transition#toString() + */ + @Override + public String toString(){ + String result = ""; + + // Check what type of events are contained in this event set. + if(_transition != null){ + // This is a set of a singleton transition. + result += "Transition Event Set = [" + _transition.getLabel(); + } + else if(_rate !=null){ + // This is a single rate change. + result += "Rate change Event set = [" + _rate; + } + else if (_inequalities != null){ + result += "Inequality Event Set = [" + _inequalities; + } + else{ + result += "Event Set = ["; + } + + result += "]"; + + return result; + } + + @Override + public String getLabel(){ + return toString(); + } + + + /** + * Determines if the EventSet represents a transition that is a failure + * transition. + * @return + * True if this EventSet is storing a failure transition; false otherwise. + */ + @Override + public boolean isFail() { + + // If this eventSet represents a transition to fire, then check if the + // Transition is a failure transition. Otherwise return false. + + return _transition != null && _transition.isFail(); + } + + /** + * This method disables (ha ha) the disablingError. It needs to be finished. + */ + @Override + public Transition disablingError(final LinkedList current_enabled_transitions, + LinkedList next_enabled_transitions) { + return null; + } + + /* + * ------------------------------------------------------------------------------------- + * Inner Class + * ------------------------------------------------------------------------------------- + */ + + /** + * This is the custom iterator for the EventSet class. It operates in one of two modes : + * the Transition mode or the Inequality mode depending on whether the EventSet that created + * it holds a Transition or a list of Inequalities. In the Transition mode the iterator + * will return the single Transition. In the Inequality mode, the Iterator will iterate + * through the Inequality variables. All elements are returned packaged as Event objects. + * @author Andrew N. Fisher + * + */ + private class EventSetIterator implements Iterator{ + + /* + * Abstraction Function : The Iterator operates in one of three modes: the + * Transition mode, the Inequality mode, or the Rate mode. The mode is + * determined by which of _tran, _inequal, or _r is non-null. + * The modes are then Transition, Inequality, or Rate mode respectively. + */ + + /* + * Representation Invariant : If the Iterator is created in a given mode, + * then it should stay in that mode. The mode is determined by which field + * is non-null. Exactly one of _tran, _inequal, or _r should be non-null. + * The _tran or _rate variable will be null in the after returning it. + */ + + // Stores the single transition if the Iterator is in the Transition mode. + Transition _tran; + + // Stores the ArrayList objects iterator if the Iterator is in the + // Inequality mode. + Iterator _inequal; + + // Stores the single rate change if the Iterator is in the Rate mode. + LPNContinuousPair _r; + + /** + * The constructor initializes an Iterator in one of three modes : the + * Transition mode, the Inequality mode, or the Rate mode. + * This mode is set once the Iterator is created. + */ + public EventSetIterator(){ + + // Check to see in the EventSet is in a consistent state. + if((_transition == null && _inequalities == null && _rate == null) + || (_transition != null && _inequalities != null) + || (_transition != null && _rate != null) + || (_inequalities != null && _rate != null)){ + throw new IllegalStateException("The EventSet is not in a correct" + + " mode."); + } + + if(EventSet.this._inequalities != null){ + // The EventSet contains inequalities. So initialize the + // EventSetIterator in Inequality mode. + _inequal = EventSet.this._inequalities.iterator(); + } + else if (EventSet.this._transition != null){ + // The EventSet contains a transition. So initialize the + // EventSetIterator in Transition mode. + _tran = EventSet.this._transition; + } + else{ + // The EventSet is not in Inequality or Transition mode, so + // it must be in Rate mode. So initialize the EventSetIterator + // to Rate mode. + _r = EventSet.this._rate; + } + } + + /* + * (non-Javadoc) + * @see java.util.Iterator#hasNext() + */ + @Override + public boolean hasNext() { + + // Determine the mode the EventSetIterator is in. + if(_inequal != null){ + //A non-null _inequal variable indicates it is in the + // Inequality mode, so pass the action to the _inequal iterator. + return _inequal.hasNext(); + } + + // The Iterator is in the Transition or Rate mode. + // So determine if there is still a transition or rate to return. + return _tran != null || _r != null; + } + + /* + * (non-Javadoc) + * @see java.util.Iterator#next() + */ + @Override + public Event next() { + + //Determine the mode the EventSetIterator is in. + if(_inequal != null){ + // The Iterator is in the Inequality mode, so pass the action + // to the _ineqaulities iterator. + return new Event(_inequal.next()); + } + + // The Iterator is in the Transition or rate mode. + if(_tran == null && _r == null){ + // The transition or rate has already been returned so complain. + throw new NoSuchElementException("No more elements to return."); + } + + // The Iterator is in the Transition or Rate mode and the + // transition or rate has not be removed. + // Remove the transition or rate and return it. + + if(_tran != null){ + Transition tmpTran = _tran; + + _tran = null; + + return new Event(tmpTran); + } + LPNContinuousPair tmpRate = _r; + _r = null; + return new Event(tmpRate); + } + + /* + * (non-Javadoc) + * @see java.util.Iterator#remove() + */ + @Override + public void remove() { + + // Determine which mode is being operated in. + if(_inequal == null){ + // We are in the Transition or Rate mode. + // This is not supported, so complain. + throw new UnsupportedOperationException("The remove method is not supported when for the EventSet" + + " iterator when in the Transition mode."); + } + _inequal.remove(); + } + + } + + /** + * Tests for equality. Overrides inherited equals method. + * @return True if o is equal to this object, false otherwise. + */ + @Override + public boolean equals(Object o) + { + // Check if the reference is null. + if(o == null) + { + return false; + } + + // Check that the type is correct. + if(!(o instanceof EventSet)) + { + return false; + } + + // Check for equality using the Zone equality. + return equals((EventSet) o); + } + + + /** + * Tests for equality. + * @param + * The EventSet + * @return + * True if the other EventSet is non-null and is equal. + */ + public boolean equals(EventSet otherEventSet) + { + // Check if the reference is null first. + if(otherEventSet == null) + { + return false; + } + + // Check for reference equality. + if(this == otherEventSet) + { + return true; + } + + // If the hash codes are different, then the objects are not equal. + if(this.hashCode() != otherEventSet.hashCode()) + { + return false; + } + + if(isTransition()){ + if(otherEventSet.isTransition()){ + // The other is also a transition, so compare the transition. + return _transition.equals(otherEventSet._transition); + } + else{ + // The other is not a transition so they are not equal. + return false; + } + } + + if(isRate()){ + if(otherEventSet.isRate()){ + // The other is also a rate rate transition, so compare. + return _rate.equals(otherEventSet._rate); + } + else{ + // They are not equal. + return false; + } + } + + if(isInequalities()){ + if(otherEventSet.isInequalities()){ + // The other is also a set of inequalities. + + if(_inequalities.size() != otherEventSet._inequalities.size()){ + return false; + } + + boolean result = true; + + for(InequalityVariable ineq: _inequalities){ + result &= otherEventSet._inequalities.contains(ineq); + } + + for(InequalityVariable ineq: otherEventSet._inequalities){ + result &= _inequalities.contains(ineq); + } + return result; + } + else{ + return false; + } + } + + System.err.print("Warning: EventSet equality reached end of equality."); + return false; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/InequalityVariable.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/InequalityVariable.java new file mode 100644 index 000000000..1b4250f24 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/InequalityVariable.java @@ -0,0 +1,772 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Properties; + +import edu.utah.ece.async.lema.verification.lpn.ExprTree; +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.lpn.Variable; +import edu.utah.ece.async.lema.verification.platu.platuLpn.DualHashMap; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.timed_state_exploration.octagon.Equivalence; + + +/** + * An InequalityVariable is a Boolean variable for an inequality expression involving + * continuous variables. It extends lpn.parser.Variable. + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class InequalityVariable extends Variable { + + + /* + * Representation Invariant : + * To create a canonical name for the variable, the name should be the string + * representation of the defining ExprTree pre-appended by a '$' to help + * avoid the possibility of name collision. Thus the variable for "x>6" is + * given the name '$x>6'. + */ + + /* Holds the defining expression for a boolean value derived from an inequality. */ + private ExprTree _inequalityExprTree; + + /* The continuous variable that this InequalityVariable depends on.*/ + //String _variable; + //Variable _variable; + private ArrayList _variables; + + /* + * Holds the Transitions that have this inequality in their enabling + * condition. + */ + private HashSet _transitions; + + /* The LhpnFile object that this InequalityVariable belongs to. */ + private LPN _lpn; + + /* + * The constant. Note: getConstant will set this variable. + */ + private Integer _constant; + + /* + * True if constant is on the right; false otherwise. + */ + private boolean _isRight; + + // Cached hash code value. + int _hashCode; + + /** + * Overrides the hashCode. + */ + @Override + public int hashCode() + { + // Check if the hash code has been set. + if(_hashCode <0) + { + _hashCode = createHashCode(); + } + + return _hashCode; + } + + /** + * Creates a hash code for an EventSet object. + * @return + * The hash code. + */ + private int createHashCode() + { + int prime = 31; + + int newHashCode = prime; + + String name = toString(); + + for(char c : name.toCharArray()){ + newHashCode *= (int) c; + } + + return Math.abs(newHashCode); + } + +// +// Not needed anymore since the list of InequalityVariables is not dynamically +// changing. +// +// /* +// * Keeps track of the Transitions that currently reference this InequalityVariable. +// */ +// //HashSet referencingTransitions; +// int _referenceCount; + + /** + * Not supported. + * @param name + * @param type + * @param initCond + */ + public InequalityVariable(String name, String type, Properties initCond) { + super(name, type, initCond); + + throw new UnsupportedOperationException("This constructor needs to be verified" + + "for correctness for inherited class InequalityVariable."); + } + + /** + * Not supported. + * @param name + * @param type + * @param initValue + * @param port + */ + public InequalityVariable(String name, String type, String initValue, + String port) { + super(name, type, initValue, port); + + throw new UnsupportedOperationException("This constructor needs to be verified" + + "for correctness for inherited class InequalityVariable."); + } + + /** + * Creates an InequalityVariable with a given name, initial value and defining + * expression tree. + * @param name + * The name (or ID) of the variable. + * @param initValue + * The initial value of the variable. Note : Inequality variables are + * a type of boolean variable. So this should be "true" or "false". + * @param ET + * An expression tree that defines the boolean value. This tree should + * represent a relational operator. + */ + public InequalityVariable(String name, String initValue, ExprTree ET, LPN lpn) { + super(name, BOOLEAN, initValue); + + // Check if the name starts with a '$'. If not, yell. + if(!name.startsWith("$")){ + throw new IllegalArgumentException("InequaltiyVariables' name" + + "must start with '$'"); + } + + // Declare the new boolean variable an internal signal. + setPort(INTERNAL); + + // Set the defining expression. + _inequalityExprTree = ET; + + // Set the containing LPN. + _lpn = lpn; + + // Initialize the the variable list. + _variables = new ArrayList(); + + // Initialize the transition list. + _transitions = new HashSet(); + // Extract the variable. +// String contVariableName = ""; +// +// if(ET.getLeftChild().containsCont()){ +// contVariableName = ET.getLeftChild().toString(); +// } +// else{ +// contVariableName = ET.getRightChild().toString(); +// } +// +// _variable = lpn.getVariable(contVariableName); + + // Register this Inequality with the continuous variable. +// +// +// Reference counts are not needed anymore since the set of +// Boolean variables is not dynamically changing. +// +// // When created, an expression refers to this variable. +// _referenceCount = 1; + + // Populate the variables member field and register the + // this InequalityVariable with the continuous variables + // it references. + initializeContinuous(); + + } + + + + /** + * @param name + * @param type + */ + public InequalityVariable(String name, String type) { + super(name, type); + + throw new UnsupportedOperationException("This constructor needs to be verified" + + "for correctness for inherited class InequalityVariable."); + } + + /** + * Overrides the toString method of Variable. Removes the pre-appended + * '$' of the InequalityVariable name. + */ + @Override + public String toString(){ + //return "Inequality Variable : " + getName().substring(1); + return getName().substring(1); + } + + /** + * Override the equals method. + */ + @Override + public boolean equals(Object var){ + /* + * Due to the fact that twoString returns the name without the '$' sign + * the equals method for variable will not work since it will end up + * comparing the name without the dollar sign to the name with. + * So we need to correct the equals to use the full name. It should + * be considered whether the equals method the Variable class should + * just be changed to type checking and then use the name subfield. + */ + + if(!(var instanceof InequalityVariable)){ + return false; + } + + // Cast the variable + InequalityVariable ineqvar = (InequalityVariable) var; + return this.name.equals(ineqvar.name); + } + +// +// This is no longer needed since variables will not dynamically change. +// +// /** +// * Increase the count of how many expressions refer to this InequalityVariable. +// */ +// public void increaseCount(){ +// _referenceCount++; +// } +// +// /** +// * Decreases the count of how many expressions refer to this InequalityVariable. +// */ +// public void decreaseCount(){ +// _referenceCount--; +// } +// +// /** +// * Returns the count of the number of expressions referring to this +// * InequalityVariable. +// * @return +// * The count recorded for how many expressions refer to this InequalityVariable. +// */ +// public int getCount(){ +// return _referenceCount; +// } + + /** + * Returns false. InequalityVaribles are dealt with separately. + */ + @Override + public boolean isInput() { + return false; + } + + /** + * Returns false. InequalityVaribles are dealt with separately. + */ + @Override + public boolean isOutput() { + return false; + } + + /** + * Returns false. InequalityVaribles are dealt with separately. + */ + @Override + public boolean isInternal() { + return false; + } + + /** + * Evaluates the inequality according to the current state and zone. + * @param localState + * The current state. + * @param z + * The zone containing the value of the continuous variable. + */ + //public void update(Zone z){ +// public String evaluateInequality(State localState, Zone z){ +// +// //This method ignores the case where the range of the continuous variable +// // stradles the bound. +// +// // +// String result = ""; +// +// /* +// * Extract the current values of the (Boolean and Integer) variables to be able +// * to obtain the value of the expression side of the inequality. This +// * may need to be changed when the bound evaluator is created and ranges are +// * allowed for the Integer variables. +// */ +// HashMap variableValues = _lpn.getAllVarsWithValuesAsString(localState.getVector()); +// +// // Determine which side of the expression tree has the continuous variable. +// if(_inequalityExprTree.getLeftChild().containsVar(_variable.getName())){ +// // Extract the value of the expression side of the inequality. +// int expressionValue = (int) _inequalityExprTree.getRightChild().evaluateExpr(variableValues); +// +// // Determine which type of inequality. +// String op = _inequalityExprTree.getOp(); +// +// if(op.equals("<") || op.equals("<=")){ +//// if(z.getUpperBoundbyContinuousVariable(_variable) <= expressionValue){ +//// this.initValue = "true"; +//// } +//// else +//// { +//// this.initValue = "false"; +//// } +// +//// this.initValue = z.getUpperBoundbyContinuousVariable(_variable) <= expressionValue +//// ? "true" : "false"; +// +// result = z.getUpperBoundbyContinuousVariable(_variable.getName(), _lpn) +// <= expressionValue ? "true" : "false"; +// } +// else{ +//// this.initValue = z.getLowerBoundbyContinuousVariable(_variable) >= expressionValue +//// ? "true" : "false"; +// +// result = z.getLowerBoundbyContinuousVariable(_variable.getName(), _lpn) +// >= expressionValue ? "true" : "false"; +// } +// +// } +// else{ +// // Extract the value of the expression side of the inequality. +// int expressionValue = (int) _inequalityExprTree.getLeftChild().evaluateExpr(variableValues); +// +// // Determine which type of inequality. +// +// String op = _inequalityExprTree.getOp(); +// +// if(op.equals("<") || op.equals("<=")){ +//// if(expressionValue <= z.getLowerBoundbyContinuousVariable(_variable)){ +//// this.initValue = "true"; +//// } +//// else +//// { +//// this.initValue = "false"; +//// } +// +//// this.initValue = expressionValue <= z.getLowerBoundbyContinuousVariable(_variable) +//// ? "true" : "false"; +// +// result = expressionValue <= +// z.getLowerBoundbyContinuousVariable(_variable.getName(), _lpn) +// ? "true" : "false"; +// } +// else{ +//// this.initValue = expressionValue >= z.getUpperBoundbyContinuousVariable(_variable) +//// ? "true" : "false"; +// +// result = expressionValue >= +// z.getUpperBoundbyContinuousVariable(_variable.getName(), _lpn) +// ? "true" : "false"; +// } +// +// } +// +// return result; +// +// } + + /** + * Evaluates the inequality based on the current state and zone. + * @param localState + * The current (local) state. + * @param z + * The current zone. + * @return + * Zero if the inequality is false, a non-zero number if the + * inequality is true. + * @throws + * IllegalStateException if the inequality cannot be evaluated to + * true or false. + */ +// public int evaluate(State localState, Zone z){ + public int evaluate(State localState, Equivalence z){ + +// // From the (local) state, extract the current values to use in the +// // evaluator. +// HashMap values = +// _lpn.getAllVarsWithValuesAsString(localState.getVector()); +// +// // Evaluate the defining expression tree. +// IntervalPair range = _inequalityExprTree.evaluateExprBound(values, z); +// +// // Check that the upper and lower bounds agree (indicating that a single +// // value was return instead of "don't know"). +// if(range.get_LowerBound() != range.get_UpperBound()){ +// // If a range of values (indicating a don't know condition) was +// // returned, yell. +// throw new IllegalStateException("When evaluating " + this + +// " on the local state " + localState + +// " with the zone " + z + +// " the result was \"don't know\", that is the " + +// " upper and lower bounds of the returned boolean " + +// " do not agree."); +// } +// +// // If the upper and lower bounds agreed, then return that value. +// +// return range.get_LowerBound(); + + + // Due to the strange way that inequalities are evaluated + // if the upper and lower bounds are equal to the + // the constant, then the rate determines the value + // of the inequality. + + // Get the variable + Variable v = _variables.get(0); + + int lpnIndex = _lpn.getLpnIndex(); + + int varIndex = _lpn.getContVarIndex(v.getName()); + + LPNContinuousPair ltPair = new LPNContinuousPair(lpnIndex, + varIndex); + + + IntervalPair range = z.getContinuousBounds(v.getName(), _lpn); + + if(range.singleValue() && + range.get_LowerBound() == this.getConstant()){ + // The upper and lower bounds are equal to the constant + // so the value of the inequality is determined by + // the rate. + + int rate = z.getCurrentRate(ltPair); + + if( rate == 0){ + // Get the inequality variable index. + int ineqIndex = _lpn.getVariableIndex(this.name); + + return localState.getVariableVector()[ineqIndex]; + } + + boolean isPositive = rate > 0; + + boolean result = isGreaterThan() == isPositive; + + return result ? 1 : 0; + } + + return evaluate(localState.getVariableVector(), z, null); + } + + /** + * Evaluates the inequality based on the current state and zone. + * @param vector + * The current value of the variables in the state. + * @param z + * The current zone. + * @return + * Zero if the inequality is false, a non-zero number if the + * inequality is true. + * @throws + * IllegalStateException if the inequality cannot be evaluated to + * true or false. + */ +// public int evaluate(int[] vector, Zone z, HashMap continuousValues){ + public int evaluate(int[] vector, Equivalence z, HashMap continuousValues){ + + // Extract the continuous variable from the zone. + + // Get the variable for the inequality. + //Variable v = _variables.get(0); + + //int lpnIndex = _lpn.getLpnIndex(); + + //int varIndex = _lpn.getContVarIndex(v.toString()); + + + + // From the (local) state, extract the current values to use in the + // evaluator. + HashMap values = + _lpn.getAllVarsWithValuesAsString(vector); + + // Evaluate the defining expression tree. + IntervalPair range = _inequalityExprTree.evaluateExprBound(values, z, continuousValues); + + // Check that the upper and lower bounds agree (indicating that a single + // value was return instead of "don't know"). + if(range.get_LowerBound() != range.get_UpperBound()){ + // If a range of values (indicating a don't know condition) was + // returned, yell. + throw new IllegalStateException("When evaluating " + this + + " on the vector " + vector + + " with the zone " + z + + " the result was \"don't know\", that is the " + + " upper and lower bounds of the returned boolean " + + " do not agree."); + } + + // If the upper and lower bounds agreed, then return that value. + + return range.get_LowerBound(); + } + + /** + * Get the type of inequality this variable represents. + * @return + * Strings "<", "<=", ">", ">=" depending on the type of inequality + * variable that this represents. + */ + public String get_op(){ + return _inequalityExprTree.getOp(); + } + + /** + * This method returns the constant of an inequality where one side + * evaluates to only a constant. It also populates the _isRigth + * field. + * @return + * The constant on one side of the inequality. + */ + public int getConstant(){ + + if(_constant != null){ + return _constant; + } + + // Find which side has the variable. + if(_inequalityExprTree.getLeftChild().containsCont()){ + // Evaluate the other side. Note : since the assumption + // is that one side evaluates to a constant, no + // HashMap should be needed for the + // evaluation, nor a zone. + + IntervalPair result = _inequalityExprTree.getRightChild() + .evaluateExprBound(null, null, null); + + // Check that the bounds are the same. + if(!result.singleValue()){ + // Scream! Something has gone wrong. + throw new IllegalArgumentException("The InequalityVariable." + + "getConstant() method evaluated to a non-trivial range."); + } + + _constant = result.get_LowerBound(); + _isRight = true; + + // Either the lower or upper bound will be fine to return. + return result.get_LowerBound(); + } + else if(_inequalityExprTree.getRightChild().containsCont()){ + // Evaluate the other side. Note : since the assumption + // is that one side evaluates to a constant, no + // HashMap should be needed for the + // evaluation. + + IntervalPair result = _inequalityExprTree.getLeftChild() + .evaluateExprBound(null, null, null); + + // Check that the bounds are the same. + if(!result.singleValue()){ + // Scream! Something has gone wrong. + throw new IllegalArgumentException("The InequalityVariable." + + "getConstant() method evaluated to a non-trivial range."); + } + + _constant = result.get_UpperBound(); + _isRight = false; + + // Either the lower or upper bound will be fine to return. + return result.get_UpperBound(); + } + +// System.err.println("Warning: the inequality " + this + +// "does not have one side equal to a constant. For no good reason " + +// "I'm assuming it is 0."); + //return 0; + + throw new IllegalStateException("The inequality " + this + " does" + + "not have one side equal to a constant."); + } + +// /** +// * Finds which child node of the defining ExprTree that contains the +// * continuous variable. +// * @return +// * The ExrTree node of the defining ExprTree containing the continuous +// * variable. +// */ +// private ExprTree findContinuous(){ +// +// +// if(_inequalityExprTree.getLeftChild().containsVar(_variable.getName())){ +// +// } +// +// return null; +// } + + /** + * This method determines if the value exceeds the constant value. + * @param value + * Value to compare. + * @return + * If this inequality variable represents 'variable>constant' or + * 'variable>=constant', then method returns truth value of + * 'value>=constant'. Otherwise this method returns the truth value + * of 'variable<=constant' + */ + public boolean exceedConstant(int value){ + + // There are four cases to consider. 'v>,>= a', 'v<,<= a', 'a>,>= v' + // and 'a<,<= v'. + String operation = get_op(); + + int constant = getConstant(); + + if(">=".contains(operation)){ + // Determine which side the constant lives on. + if(_isRight){ + return value >= constant; + } + return value <= constant; + } + // Determine which side the constant lives on. + if(_isRight){ + return value <= constant; + } + return value >= constant; + + } + + /** + * Adds the continuous variables that this InequalityVariable depends on + * and registers this InqualityVariable with these continuous variables. + */ + private void initializeContinuous(){ + + // Get the continuous variables named in the inequality. + ArrayList variableNames = _inequalityExprTree.getContVars(); + + for(String name : variableNames){ + // Get variable. + Variable v = _lpn.getVariable(name); + + // Added each variable to the member variable. + _variables.add(v); + + // Register this inequality variable with the continuous variable + // if it is not already registered. + if(v.getInequalities() == null || !v.getInequalities().contains(this)){ + v.addInequalityVariable(this); + } + } + + } + + /** + * Get the LPN that contains this variable. + * @return + * The LPN that contains this variable. + */ + public LPN get_lpn(){ + return _lpn; + } + + /** + * Get the continuous variables that this inequality variable + * depends on. + * + * @return + * The continuous variables that this inequality variable + * depends on. + */ + public ArrayList getContVariables(){ + return _variables; + } + + /** + * Gets the index of this Inequality variable as a Boolean variable + * in the associated LPN. + * @return + * The index in the LPN. + */ + public int get_index(){ + DualHashMap indexMap = _lpn.getVarIndexMap(); + return indexMap.getValue(getName()); + } + + /** + * Registers a Transition with this IneqaualityVaraible. + * @param t + * A Transition that has this InequalityVariable in its enabling condition. + */ + public void addTransition(Transition t){ + _transitions.add(t); + } + + /** + * Get the Transitions that have this Inequality variable in their enabling condition. + * @return + * The set of all Transitions that have this Inequality variable in their enabling condition. + */ + public HashSet getTransitions(){ + return _transitions; + } + + /** + * Determines if this is an inequality of the form + * v>=a, v>a, a<=v or a=a, v>a, a<=v or a")) || (!_isRight && getName().contains("<")); + } + + /** + * Determines if this is an inequality of the form + * v<=a, v=v, or a>v. + * @return + * True if this is an inequality of the form + * v<=a, v=v, or a>v; false otherwise. + */ + public boolean isLessThan(){ + return !isGreaterThan(); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/IntervalPair.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/IntervalPair.java new file mode 100644 index 000000000..458b24037 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/IntervalPair.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + + +/** + * An interval pair is a pair of integers representing a range of values by giving + * the upper and lower bounds for that range. They should be thought of as the + * interval [a,b] where a and b are integers. + * + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class IntervalPair { + + // The lower bound of the interval. + private int _lowerBound; + + // The upper bound of the interval. + private int _upperBound; + + /** + * Define an interval with the appropriate upper and lower bounds. + * @param lowerBound + * @param upperBound + */ + public IntervalPair(int lowerBound, int upperBound) { + this._lowerBound = lowerBound; + this._upperBound = upperBound; + } + + /** + * Defines an interval with upper and lower bounds set to zero, thus representing + * the point {0}. + */ + public IntervalPair(){ + this._lowerBound = 0; + this._upperBound = 0; + } + + /** + * Gets the lower bound for the interval. + * @return + */ + public int get_LowerBound() { + return _lowerBound; + } + + /** + * Sets the lower bound for the interval. + * @param lowerBound + */ + public void set_LowerBound(int lowerBound) { + this._lowerBound = lowerBound; + } + + /** + * Gets the upper bound for the interval. + * @return + */ + public int get_UpperBound() { + return _upperBound; + } + + /** + * Set the upper bound for the interval. + * @param upperBound + */ + public void set_UpperBound(int upperBound) { + this._upperBound = upperBound; + } + + /** + * Determines whether this IntervalPair represents a single value. + * @return + * True if lower bound is equal to upper bound. + */ + public boolean singleValue(){ + return _lowerBound == _upperBound; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + _lowerBound; + result = prime * result + _upperBound; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + IntervalPair other = (IntervalPair) obj; + if (_lowerBound != other._lowerBound) + return false; + if (_upperBound != other._upperBound) + return false; + return true; + } + + @Override + public String toString(){ + return "[" + _lowerBound + "," + _upperBound + "]"; + } + + /** + * Returns the rate in the range with the smallest absolute value + * or zero if 0 is in the range. + * @return + * Let [a,b] be the range of rates. Returns 0 if a<00){ + return 0; + } + + return Math.abs(_lowerBound)Math.abs(_upperBound)? + _lowerBound : _upperBound; + } + + /** + * Determines if zero is this range. + * @return True if the lower bound is less than or equal to zero and + * the upper bound is greater than or equal zero; false otherwise. + */ + public boolean containsZero(){ + return _lowerBound<0 && _upperBound>0 || _lowerBound == 0 || _upperBound == 0; + } + + /** + * Determines if this interval is just the value zero. + * @return True if the interval is just the zero singleton. + */ + public boolean isZero(){ + return singleValue() && _lowerBound == 0; + } + + /** + * Determines if zero lies strictly in the range. + * @return True if the lower bound is strictly less than zero and + * the upper bound is strictly greater than zero. + */ + public boolean strictlyContainsZero(){ + return _lowerBound<0 && _upperBound>0; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/LPNContAndRate.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/LPNContAndRate.java new file mode 100644 index 000000000..124d80c2e --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/LPNContAndRate.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + +/** + * An LPNContAndRate object is a pairing of an LPNcontinuousPair (for referencing) + * and an IntervalPair (for storing the rate). The purpose of the object + * is to store a variable with its associated rate. + * + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class LPNContAndRate { + + // The continuous variables reference information. + LPNContinuousPair _lcPair; + + // The possible rates for the variable. + IntervalPair _rateInterval; + + /** + * Combines an LPNContinuousPair with the continuous variables range of + * rates. + * @param _lcPair + * The LPNContinuousPair for the continuous variable. + * @param _rateInterval + * The range of possible rates. + */ + public LPNContAndRate(LPNContinuousPair _lcPair, IntervalPair _rateInterval) { + this._lcPair = _lcPair; + this._rateInterval = _rateInterval; + } + + /** + * Constructs an LPNContAndRate with no set rate information. The intent is + * to set the rate later. + * @param _lcPair + * The reference for the variable. + */ + public LPNContAndRate(LPNContinuousPair _lcPair){ + this._lcPair = _lcPair; + this._rateInterval = new IntervalPair(); + } + + /** + * Gets the LPNContinuousPair reference for this LPNContAndRate. + * @return + */ + public LPNContinuousPair get_lcPair() { + return _lcPair; + } + + + /** + * Sets the LPNContinuousPair reference for this LPNContAndRate. + * @param _lcPair + */ + public void set_lcPair(LPNContinuousPair _lcPair) { + this._lcPair = _lcPair; + } + + /** + * Gets the rates. + * @return + * Returns an IntervalPair object that contains the upper and lower bounds + * for the rate. + */ + public IntervalPair get_rateInterval() { + return _rateInterval; + } + + /** + * Sets the rate interval. + * @param _rateInterval + */ + public void set_rateInterval(IntervalPair _rateInterval) { + this._rateInterval = _rateInterval; + } + + /** + * An LPNContAndRAte variable is equal to an LPNContinuouPair or another + * LPNContAndRate variable if they refer to the same variable as defined + * by the LPNContinuousPair portion of the LPNContAndRate variable. It is + * not equal to objects that are not one of these two types. + */ + @Override + public boolean equals(Object other){ + + if(other instanceof LPNContinuousPair){ + LPNContinuousPair otherLCPair = (LPNContinuousPair) other; + return _lcPair.equals(otherLCPair); + } + else if(other instanceof LPNContAndRate){ + LPNContAndRate otherLCAR = (LPNContAndRate) other; + return _lcPair.equals(otherLCAR._lcPair); + } + + return false; + } + + @Override + public String toString(){ + return _lcPair.toString() + " " +_rateInterval.toString(); + } + + @Override + public int hashCode(){ + return _lcPair.hashCode(); + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/LPNContinuousPair.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/LPNContinuousPair.java new file mode 100644 index 000000000..445f3bff2 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/LPNContinuousPair.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + +/** + * This class is used for indexing a continuous variable in the Zone class. It pairs the index of the LPN + * with the index of the continuous variables and stores the current rate of the continuous variable. + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class LPNContinuousPair extends LPNTransitionPair { + + int _currentRate; + + /** + * Create an LPNContinuousPair where both indecies are 0 and the current rate is zero. + */ + public LPNContinuousPair() { + super(); + _currentRate = 0; + } + + /** + * Creates an LPNContinuousPair with the given indecies and current rate. + * @param lpnIndex + * The index of the LPN associate with this variable. + * @param continuousIndex + * The index of the continuous variable in the LPN. + * @param currentRate + * The current rate of the continuous variable. + */ + public LPNContinuousPair(int lpnIndex, int continuousIndex, int currentRate) { + super(lpnIndex, continuousIndex); + _currentRate = currentRate; + } + + /** + * Creates an LPNContinuousPair with the give indexcies and a current rate of zero. + * @param lpnIndex + * @param continuousIndex + */ + public LPNContinuousPair(int lpnIndex, int continuousIndex) { + super(lpnIndex, continuousIndex); + _currentRate = 0; + } + + @Override + public int hashCode() { + //final int prime = 37; + int result = super.hashCode(); + //result = result * prime + _currentRate; + + return result; + } + + @Override + public boolean equals(Object obj) { + + + if(!super.equals(obj)){ + // If they are not equal as + // LPNtransitionPairs, they are not equal. + return false; + } + + if(!(obj instanceof LPNContinuousPair)){ + return false; + } + + //LPNContinuousPair lcPair = (LPNContinuousPair) obj; + + //return this._currentRate == lcPair._currentRate; + return true; + } + + @Override + public String toString() { + String result = ""; + + result += "(LPN Index, Continuous Index) = ("; + + result += _lpnIndex + ", " + _transitionIndex + ")"; + + result += " Current rate = " + _currentRate; + + return result; + } + + @Override + public LPNContinuousPair clone() { + LPNContinuousPair newPair = new LPNContinuousPair(); + + newPair._lpnIndex = this._lpnIndex; + newPair._transitionIndex = this._transitionIndex; + newPair._currentRate = this._currentRate; + + return newPair; + } + + /** + * Returns the continuous variable's index. This method is simply a wrapper + * for the inherited get_transitionIndex provided to give that method a + * more appropriate name. + * @return + * The index of the continuous variable. + */ + public int get_ContinuousIndex(){ + return get_transitionIndex(); + } + + /** + * Sets the continuous variables index. This method is simply a wrapper for the + * inherited set_transitionIndex provided to give that method a more approriate + * name. + * @param continuousIndex + * The index of the continuous variable in the associated LPN. + */ + public void set_ContinuousIndex(int continuousIndex){ + set_transitionIndex(continuousIndex); + } + + /** + * Get the current rate of the continuous variable. + * @return + * The current rate of the continuous variable. + */ + public int getCurrentRate(){ + return _currentRate; + } + + /** + * Sets the current rate of the continuous variable. + * @param currentRate + * The current rate of the continuous variable this index refers to. + */ + public void setCurrentRate(int currentRate){ + _currentRate = currentRate; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/LPNTransitionPair.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/LPNTransitionPair.java new file mode 100644 index 000000000..e41618c83 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/LPNTransitionPair.java @@ -0,0 +1,319 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + +/** + * The LPNTransitionPair gives a packaged pairing of a transition index together + * with the index of the LPN that the transition is in. The class simply has the two + * member variables for the transition index and the LPN index with getters and + * setters, so it is possible to use it as a general pairing of two integers. However, + * it is recommended that it is only used where the semantics apply. That is, it + * is recommended that it is only used in the context of pairing a transition index + * with an LPN index. + * + * If the index of a Transition is t and the index of the LPN that the Transition + * occurs in in l, the LPNTransitionPair is thought of as (l,t). In particular, the + * natural ordering on the LPNTransitionPair is the dictionary ordering on this + * pairs of this form. + * + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class LPNTransitionPair implements Comparable{ + + /* + * + * TODO : This will need to be changed to reflect the introduction of the continuous + * variables. + * + * Abstraction Function : Given a Transition with index t in an LPN that has + * index l, the LPNTransitionPair represents the pairing (t, l). The + * index of the transition (t) is stored in _transitionIndex and the index + * of the LPN (l) is stored in _lpnIndex. + */ + + /* + * Representation Invariant : none. + */ + + // Value for indicating a single LPN is in use. + public static final int SINGLE_LPN = -3; + + // Value for indicating the zero timer. + public static final int ZERO_TIMER = -1; + + //public static final LPNTransitionPair ZERO_TIMER_PAIR = new LPNTransitionPair(ZERO_TIMER,ZERO_TIMER,true); + public static final LPNTransitionPair ZERO_TIMER_PAIR = new LPNTransitionPair(ZERO_TIMER,ZERO_TIMER); + + + protected int _lpnIndex; + protected int _transitionIndex; + //private boolean _isTimer; + + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + _lpnIndex; + result = prime * result + _transitionIndex; + + //int boolValue = _isTimer ? 1 : 0; + + //result += prime *result*boolValue; + + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof LPNTransitionPair)) + return false; + LPNTransitionPair other = (LPNTransitionPair) obj; +// if(_isTimer != other._isTimer) +// return false; + if (_lpnIndex != other._lpnIndex) + return false; + if (_transitionIndex != other._transitionIndex) + return false; + return true; + } + + /** + * Creates a LPNTransitionPair with both indicies set to 0. + */ + public LPNTransitionPair(){ + _lpnIndex = 0; + _transitionIndex = 0; + //_isTimer = false; + } + + /** + * Creates a pairing of an LPN index and is associated transition index. + * @param lpnIndex + * The LPN that the transition is in. + * @param transitionIndex + * The index of the transition. + */ +// public LPNTransitionPair(int lpnIndex, int transitionIndex, boolean isTimer){ +// this._lpnIndex = lpnIndex; +// this._transitionIndex = transitionIndex; +// this._isTimer = isTimer; +// } + + public LPNTransitionPair(int lpnIndex, int transitionIndex){ + this._lpnIndex = lpnIndex; + this._transitionIndex = transitionIndex; + } + + /** + * Gets the index of the LPN that the transition is in. + * @return + * The index of the LPN that the transition is in. + */ + public int get_lpnIndex() { + return _lpnIndex; + } + + /** + * Sets the index of the LPN that the transition is in. + * @param lpnIndex + * The index of the Lpn that the transition is in. + */ + public void set_lpnIndex(int lpnIndex) { + this._lpnIndex = lpnIndex; + } + + /** + * Get the index of the transition. + * @return + * The index of the transition. + */ + public int get_transitionIndex() { + return _transitionIndex; + } + + /** + * Sets the index of the transition. + * @param transitionIndex + * The index of the transition. + */ + public void set_transitionIndex(int transitionIndex) { + this._transitionIndex = transitionIndex; + } + + /** + * Gets a boolean value that indicates whether this pair is storing a timer + * or a continuous variable. + * @return + * True if the pair is to be interpreted as a timer, false if it is to be + * interpreted as a continuous variable. + */ +// public boolean get_isTimer(){ +// return _isTimer; +// } + + /** + * Sets the boolean that's used to determine if the pairing should be treated + * as a continuous variable or a timer. + * @param isTimer + * True indicates a timer, false indicates a continuous variables. + */ +// public void set_isTimer(boolean isTimer){ +// this._isTimer = isTimer; +// } + + /** + * Creates a string representation of the LPNTransitionsPair object. If + * the pairing is representing a timer then the format is in the form + * "(LPN Index, Transition Index) = (x, y)" where x and y are the LPNIndex + * and Transition Index, respectively. If the pairing is representing a + * continuous variable the format is in the form + * "(LPN Index, Continuous Variable) = (x, y)" where x and y are the LPNIndex + * and the index of the continuous variable, respectively. + */ + @Override + public String toString(){ + String result = ""; + +// if(_isTimer){ +// + if(this.equals(ZERO_TIMER_PAIR)){ + result += "Zero timer"; + } + else{ + result += "(LPN Index, Transition Index) = ("; + + result += _lpnIndex + ", " + _transitionIndex + ")"; + } +// } +// else{ +// result = "(LPN Index, Continuous Variable) = ("; +// +// result += _lpnIndex + ", " + _transitionIndex + ")"; +// } + + return result; + } + + /* + * (non-Javadoc) + * @see java.lang.Object#clone() + */ + @Override + public LPNTransitionPair clone(){ + + LPNTransitionPair newPair = new LPNTransitionPair(); + + newPair._lpnIndex = this._lpnIndex; + newPair._transitionIndex = this._transitionIndex; + //newPair._isTimer = this._isTimer; + + return newPair; + } + + /** + * Determines whether this LPNTransitionPair is less than the otherPair + * LPNTransitionPair. The ordering is the dictionary ordering on pairs + * (l,t) where t is the index of the Transition and l is the index of the + * LPN that the Transition is in. All continuous variables come before all + * timers. + * @param otherValue + * The value to determine whether this LPNTransitionPair is less than. + * @return + * A negative integer, zero, or positive integer depending on if this + * LPNTransitionPair is less than, equal, or greater than the otherPair + * LPNTransitionPair. + */ + @Override + public int compareTo(LPNTransitionPair otherPair) { + + /* + * If it is known that the terms will not be too large, than a clever + * implementation would be + * return dlpnIndex * constant + dtransitionIndex + * where dlpnIndex is the difference in the _lpnIndex member variables and + * dtransitionIndex is the difference in the _transitionIndex member variables. + * + * For this to work the constant has to be chosen such that + * |dtransitionIndex| < constant + * so that the return value has the proper sign when dlpnIndex and + * dtransitionIndex have opposite signs. Since the number of transition + * is not bounded, this is not practical. + * + * The roles of dlpnIndex and dtransitionIndex could be reversed (that is + * we could do the dictionary ordering of the reversed pair). But the problem + * still remains and this ordering would be much less intuitive. + */ + + /* + * This block ensures that all continuous variables (ie _isTimer is false) + * come before the timers. However, if one of the timers is the zero timer, + * then we want o skip this block. The the reason is that the zero timer + * comes before any continuous variable or timer and this will already be + * enforced if this block is skipped due to the _lpnIndex field of the zero + * timer is smaller than the possible indicies of any other variable. + */ +// if(this._isTimer != otherPair._isTimer && +// !(this._lpnIndex == ZERO_TIMER || otherPair._lpnIndex == ZERO_TIMER)){ +// // If one pair represents a continuous variable and the other represents a timer +// // then already one is less than the other. If this._isTimer is false, then +// // otherPair._isTimer is true and this comes before otherPair. Else this._isTimer +// // is true and otherPair._isTimer is false. So this comes after otherPair. +// return this._isTimer ? 1 : -1; +// } + + + if((this instanceof LPNContinuousPair != otherPair instanceof LPNContinuousPair) + && !(this.equals(ZERO_TIMER_PAIR) || otherPair.equals(ZERO_TIMER_PAIR))){ + // Continuous variables come before all timers except the zero timer. In this block + // exactly one of this pair and other pair is a continuous variable index. If this + // is the continuous variable index, then this is smaller. If this is not the + // continuous variable, then the other is the continuous variable, so this pair is + // larger. + return (this instanceof LPNContinuousPair) ? -1 : 1; + } + + int dlpnIndex = this._lpnIndex - otherPair._lpnIndex; + + if(dlpnIndex != 0){ + return dlpnIndex; + } + // Reaching here means that the first values are equal. + // So the sign is determined by the second pair. + return this._transitionIndex - otherPair._transitionIndex; + } + + +// public LPNTransitionPair (int a, int b, boolean c){ +// // remove when Zones dependency have been addressed. +// } + +// public boolean get_isTimer(){ +// // remove when Zones dependency have been addressed. +// return false; +// } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/RangeAndPairing.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/RangeAndPairing.java new file mode 100644 index 000000000..447edc898 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/RangeAndPairing.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class RangeAndPairing { + + private LPNTransitionPair _indexPair; + + private IntervalPair _range; + + public RangeAndPairing(LPNTransitionPair _indexPair, IntervalPair _range) { +// super(); + this._indexPair = _indexPair; + this._range = _range; + } + + public LPNTransitionPair get_indexPair() { + return _indexPair; + } + + public void set_indexPair(LPNTransitionPair _indexPair) { + this._indexPair = _indexPair; + } + + public IntervalPair get_range() { + return _range; + } + + public void set_range(IntervalPair _range) { + this._range = _range; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((_indexPair == null) ? 0 : _indexPair.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof RangeAndPairing)) + return false; + RangeAndPairing other = (RangeAndPairing) obj; + if (_indexPair == null) { + if (other._indexPair != null) + return false; + } else if (!_indexPair.equals(other._indexPair)) + return false; + return true; + } + + + @Override + public String toString(){ + return "Index Pair : " + _indexPair + " : Range : " + _range; + } + +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/StateSet.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/StateSet.java new file mode 100644 index 000000000..bddbd479c --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/StateSet.java @@ -0,0 +1,628 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; + +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.project.PrjState; + +/** + * A StateSet object operates like a hash set of PrjState objects. It operates in one + * of two modes. The first mode (called the set mode) is exactly like a HashSet. + * The second mode is backed by a HashMap>. This + * second mode (called the subset/superset mode) allows TimedPrjStates to be keyed by + * their un-timed portions for quicker look-up when determining subsets and supersets. + * The subset/superset mode is only enacted when the Options.getTimingAnalysisFlag() is + * true and at least one of the ZoneType.getSubsetFlag() or ZoneType.getSupersetFlag() is + * true. + * + * Note: this object acts differently + * depending on whether + * Options.getTimingAnalysisFlag() + * && (ZoneType.getSubsetFlag() || ZoneType.getSupersetFlag()) + * is true or not. If this value is false, then the StateSet acts like HashSet. + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class StateSet implements Iterable{ + + /* + * Abstraction Function: The StateSet object follows one of two modes for storing + * elements called the set mode and the subset/superset mode. In the set mode + * elements are simply stored in a HashSet _singletonList. In this + * mode the StateSet simply a wrapper of the HashSet and passes + * the operations to the _singletonList. + * + * In the subset/superset mode, elements are stored in _setList. The idea of is + * to be able to take the un-timed portion of a TimedPrjState (which can be thought + * of as a PrjState) use it as a key and have return all TimedPrjStates in the + * StateSet that share the same un-timed portion. Thus the key value pair + * (k, v) of the HashMap should be such that v is a list containing only + * TimedPrjStates that have the same un-timed portion k. + */ + + /* + * Representation Invariant: Only one of _singletonList or _setList should + * be non-null at a time and should correspond to whether the StateSet is in the + * subset/superset mode or not. Furthermore, if the StateSet is operating in the + * subset/superset mode, then it is the _setList that should be non-null. + * The mode is set in the constructor and should not change as long as the object + * is in existence. + * + * In the set mode, operations should be simply passed to the _singletonList + * thereby ensuring that the StateSet acts identical to a HashSet in this mode. + * + * Given a key value pair (k, v) stored in the _setList, the LinkedList v should + * only contain TimedPrjStates that have an un-timed portion equal to k. Specifically, + * s.getUntimedPrjState.equals(k) should return true for each TimedState in v. + */ + + protected HashSet _singletonList; + protected HashMap> _setList; + + // Caches whether subsets, supersets, and timing is being used. + private boolean timed, subsets, supersets; + + private PrjState _initState; + + /* + * Get the initial state. + */ + public PrjState get_initState() { + return _initState; + } + + /* + * Set the initial state. + * @param initState + * The initial state. + */ + public void set_initState(PrjState initState) { + this._initState = initState; + } + + /** + * Creates a state set. The StateSet will be initialized into the into the subset/superset + * mode if the expression + * Options.getImingAnalysisFlag() && (ZoneType.getSubsetFlag() || + * ZoneType.getSupersetFlag()) + * is true. Otherwise the StateSet will be initialized into the set mode. Once the + * StateSet is initialized in the set mode or the subset/superset mode, it cannot be + * changed. + */ + public StateSet(){ + + // Store that status when StateSet is initialized to avoid unexpected behavior. + timed = Options.getTimingAnalysisFlag(); + subsets = Zone.getSubsetFlag(); + supersets = Zone.getSupersetFlag(); + + if(timed && (subsets || supersets)){ + _setList = new HashMap>(); + } + else{ + _singletonList = new HashSet(); + } + } + +// public StateSet(boolean map){ +// if(map){ +// _setList = new HashMap>(); +// } +// else{ +// _singletonList = new HashSet(); +// } +// } + + /** + * Determines whether the any PrjStates are in the StateSet. + * @return + * True if any PrjStates are in the StateSet, false otherwise. + */ + public boolean isEmpty(){ + if(_singletonList != null){ + return _singletonList.isEmpty(); + } + return _setList.isEmpty(); + } + + /** + * Determines how many PrjStates are in the StateSet. + * @return + * A non-negative integer that gives the number of PrjStates are in the StateSet. + */ + public int size(){ + if(_singletonList != null){ + return _singletonList.size(); + } + int result = 0; + + for(LinkedList l : _setList.values()){ + result += l.size(); + } + + return result; + } + + /** + * Adds a PrjState to the StateSet. + * @param s + * The PrjState to add to the StateSet. + * @return + * True if the StateSet changes by adding the element s. + */ + public boolean add(PrjState s){ + + if(_singletonList != null){ + return _singletonList.add(s); + } + + if(_setList != null){ + + if(!(s instanceof TimedPrjState)){ + throw new IllegalArgumentException("Subset/superset mode set, but an un-timed" + + "state is being added."); + } + + TimedPrjState ts = (TimedPrjState) s; + + PrjState untimedState = ts.getUntimedPrjState(); + + LinkedList list = _setList.get(untimedState); + + if(list == null){ + + // No list is associated with this set of un-timed (local) states. + // So create a new list with this PrjState. + LinkedList newList = new LinkedList(); + newList.add(ts); + _setList.put(untimedState, newList); + + // The list changed, so return true; + return true; + } + + if(list.contains(ts)){ + // The set already contains the timed project state. So nothing changes. + return false; + } + // The set does not already contain the timed project state. So add it. + list.add(ts); + + + return true; + } + + throw new IllegalStateException("Add was used and StateSet was not initialized."); + } + +// public boolean add(PrjState s){ +// if(s instanceof TimedPrjState){ +// TimedPrjState ts = (TimedPrjState) s; +// return add(ts); +// } +// else if(_singletonList == null){ +// throw new IllegalArgumentException("StateSet initialized in subset/superset mode," + +// " but only an un-timed state is being added."); +// } +// +// return _singletonList.add(s); +// } +// +// +// public boolean add(TimedPrjState s){ +// if(_setList == null){ +// throw new IllegalArgumentException("StateSet initialized as un-timed, " + +// " but a timed project state is attempted to be added."); +// } +// +// PrjState untimedState = s.getUntimedPrjState(); +// +// LinkedList list = _setList.get(untimedState); +// +// if(list == null){ +// +// // No list is associated with this set of un-timed (local) states. +// // So create a new list with this PrjState. +// LinkedList newList = new LinkedList(); +// newList.add(s); +// _setList.put(untimedState, newList); +// +// // The list changed, so return true; +// return true; +// } +// +// if(list.contains(s)){ +// // The set already contains the timed project state. So nothing changes. +// return false; +// } +// else{ +// // The set does not already contain the timed project state. So add it. +// list.add(s); +// } +// +// +// return true; +// } + + /** + * Determines whether the StateSet contains the PrjState or not. + * @param s + * The PrjState to determine if the PrjState contains it. + * @return + * True if s is in the PrjState, false otherwise. + */ + public boolean contains(PrjState s){ + if(_singletonList != null){ + return _singletonList.contains(s); + } + + if(_setList != null){ + // If _setList != null, then StateSet has been initialized into subset/superset mode. + // Thus there are three possibilities : subsets has been selected, supersets has been + // selected, or both subsets and supersets have been selected. + + + if(!(s instanceof TimedPrjState)){ + throw new IllegalArgumentException("Subset/superset mode set, but an un-timed" + + "state is being added."); + } + + TimedPrjState ts = (TimedPrjState) s; + + // Get the un-timed portion for the cache. + PrjState untimedState = ts.getUntimedPrjState(); + + // Get the list keyed to this set of (local) un-timed states. + LinkedList list = _setList.get(untimedState); + + if(list == null){ + + // No list is associated with this set of un-timed (local) states. + // So the timed state cannot be in the set. + + return false; + } + + // Get an iterator from the list to allow removal of elements as the list is + // traversed. + Iterator iterate = list.iterator(); + + boolean result = false; + + while(iterate.hasNext()){ + TimedPrjState listState = iterate.next(); + + // If subsets are selected, then iteration can be exited as soon as a subset is found. + if(subsets && ts.subset(listState)){ + return true; + } + + // If supersets are selected, items that are subsets of the new state may be + // removed. + if(supersets){ + if(!subsets && ts.equals(listState)){ + // When an equal state is found, the return value must be true and the + // state should not be removed. When not doing subsets, the superset check + // cannot end here (since other sets that are supersets may exist further in the + // list). If control has passed here, it can be deduced that subsets has not + // been selected even without the subset flag since the + // if(subsets && s.subset(listState) would have already been taken. + // The subset flag is added here to allow a quick out of the extra equality check. + result |= true; + } + else if(ts.superset(listState)){ + // The new state (s) is a strict superset of an existing state. + // Remove the existing state. + iterate.remove(); + } + } + + } + + return result; + } + + throw new IllegalStateException("Contains was called and StateSet was not initialized."); + } + + +// public boolean contains(PrjState s){ +// if(s instanceof TimedPrjState){ +// TimedPrjState ts = (TimedPrjState) s; +// return contains(ts); +// } +// else if(_singletonList == null){ +// throw new IllegalArgumentException("StateSet initialized as timed," + +// " but only an untimed state is being added."); +// } +// +// return _singletonList.contains(s); +// } +// +// public boolean contains(TimedPrjState s){ +// if(_setList == null){ +// throw new IllegalArgumentException("StateSet initialized as untimed, " + +// " but a timed project state is attempted to be added."); +// } +// +// // If _setList == null, then StateSet has been initialized into subset/superset mode. +// // Thus there are three possibilities : subsets has been selected, supersets has been +// // selected, or both subsets and supersets have been selected. +// +// // Get the un-timed portion for the cache. +// PrjState untimedState = s.getUntimedPrjState(); +// +// // Get the list keyed to this set of (local) untimed states. +// LinkedList list = _setList.get(untimedState); +// +// if(list == null){ +// +// // No list is associated with this set of un-timed (local) states. +// // So the timed state cannot be in the set. +// +// return false; +// } +// +// //return list.contains(s); +// +// // Get an iterator from the list to allow removal of elements as the list is +// // traversed. +// Iterator iterate = list.iterator(); +// +// boolean result = false; +// +// while(iterate.hasNext()){ +// TimedPrjState listState = iterate.next(); +// +// // If subsets are selected, then iteration can be exited as soon as a subset is found. +// if(subsets && s.subset(listState)){ +// return true; +// } +// +// // If supersets are selected, items that are subsets of the new state may be +// // removed. +// if(supersets){ +// if(!subsets && s.equals(listState)){ +// // When an equal state is found, the return value must be true and the +// // state should not be removed. When not doing subsets, the superset check +// // cannot end here (since other sets that are supersets may exist further in the +// // list). If control has passed here, it can be deduced that subsets has not +// // been selected even without the subset flag since the +// // if(subsets && s.subset(listState) would have already been taken. +// // The subset flag is added here to allow a quick out of the extra equality check. +// result |= true; +// } +// else if(s.superset(listState)){ +// // The new state (s) is a strict superset of an existing state. +// // Remove the existing state. +// iterate.remove(); +// } +// } +// +// } +// +// return result; +// } + + /** + * Converts the StateSet into a HashSet. + * @return + * A HashSet containing the same PrjStates as the StateSet. + */ + public HashSet toHashSet(){ + if(_singletonList != null){ + return _singletonList; + } + HashSet result = new HashSet(); + //throw new IllegalStateException("Array initialized in subset/superset mode."); + for(LinkedList list : _setList.values()){ + result.addAll(list); + } + return result; + } + + public String stateString(){ + + String result = ""; + + if(_singletonList != null){ + result += "# of prjStates found: " + size(); + } + + if(_setList != null){ + // Report the total number of project states found. + result += "# of timedPrjStates found: " + size(); + + // Report the number of un-timed states. + result += ", # of untimed states found: " + _setList.size(); + + // Report the largest Zone used. + result += ", Largest zone: " + Zone.ZoneSize; + } + + return result; + } + + /* + * (non-Javadoc) + * @see java.lang.Iterable#iterator() + */ + @Override + public Iterator iterator(){ + Iterator hashIterator = null; + Iterator> listIterator = null; + + if(_singletonList != null){ + hashIterator = _singletonList.iterator(); + } + + if(_setList != null){ + listIterator = _setList.values().iterator(); + } + + + return new StateSetIterator(hashIterator, listIterator); + } + + /** + * This is the particular version of the iterator that the StateSet uses. + * @author Andrew N. Fisher + * + */ + private class StateSetIterator implements Iterator{ + + /* + * Abstraction Function: + * A StateSetIterator is the implementation for the Iterator + * required by StateSet being iterable. The StateSet has two modes, + * one where a HashSet is used and one where a + * HashMap> is used. Correspondingly, + * This iterator has two modes. One that is meant iterate through the + * HashSet and the other that is meant to iterate through the HashMap. + * The member variable _hashIterator is simply the HashSet's own iterator. + * The member variables _hashListIterator and _listIterator together + * iterate through all the TimedPrjStates that are stored in the LinkedLists + * of a HashMap>. The _hashListIterator + * iterator goes through each of the LinkedList and the _listIterator goes + * through a single list. Thus the idea is to get the first LinkedList, + * traverse its elements, get the second LinkedList, traverse its elements + * and so on until all elements of the LinkedLists have been traversed. + */ + + + /* + * Representation Invariant : Only one of _hashIterator or _hashListIterator + * should be non-null at one time. The iterator should be iterating through + * one mode at a time, either the HashSet mode or the LinkedList mode. + * + * If _hashListIterator is not null, then _listIterator should either + * be the iterator for the last LinkedList returned by _hashListIterator + * or an iterator that has not exhausted all its elements. The idea is + * the _listIterator should be able to give the next element that is to + * be return if there are still elements that can be returned. + */ + + Iterator _hashIterator; + Iterator> _hashListIterator; + Iterator _listIterator; + + /** + * Initializes the iterator. Only one parameter should be non-null when this + * object is created matching one of the two modes of the StateSet object, + * it throws an IllegalStateExceptoin otherwise. + * @param hashIterator + * Iterator for a HashSet>. + */ + private StateSetIterator(Iterator hashIterator, + Iterator> listIterator){ + + // This method initializes the iterator for the StateSet. It initializes + // the iterator member variables. The member variables that are initialized + // should match the mode that the StateSet is in. This method may be made + // to check the member variables directly, but currently determines things + // by the variables passed. The HashIterator should be an iterator for the + // __singletonList member variable of the StateSet and the listIterator + // should be an iterator for the _setList member variable of the StateSet. + // In keeping with only one mode being initialized, only one of the member + // variables can be non-null. + if(hashIterator != null && listIterator !=null){ + throw new IllegalStateException("Only one iterator should be non-null."); + } + + _hashIterator = hashIterator; + _hashListIterator = listIterator; + + + if(_hashListIterator != null && _hashListIterator.hasNext()){ + _listIterator = _hashListIterator.next().iterator(); + + // Find the first list with an element or end with the last list. + while( !_listIterator.hasNext() && _hashListIterator.hasNext()){ + _listIterator = _hashListIterator.next().iterator(); + } + } + } + + /* + * (non-Javadoc) + * @see java.util.Iterator#hasNext() + */ + @Override + public boolean hasNext() { + + if(_hashIterator !=null){ + return _hashIterator.hasNext(); + } + + if(_listIterator == null){ + return false; + } + + return _listIterator.hasNext(); + } + + /* + * (non-Javadoc) + * @see java.util.Iterator#next() + */ + @Override + public PrjState next() { + + if(_hashIterator != null){ + return _hashIterator.next(); + } + + PrjState nextState = _listIterator.next(); + + // If this list is exhausted, find the next list with elements or + // get the last list. + while( !_listIterator.hasNext() && _hashListIterator.hasNext()){ + _listIterator = _hashListIterator.next().iterator(); + } + + return nextState; + } + + /* + * (non-Javadoc) + * @see java.util.Iterator#remove() + */ + @Override + public void remove() { + if(_hashIterator != null){ + _hashIterator.remove(); + return; + } + + // TODO: This has the following flaw currently. Suppose list1 and lists2 are two + // nonempty consecutive lists. Once next is called on the last element in list1, + // list2 becomes the new _listIterator. If removed is called, it will be called on list2 + // instead of list1 causing an error. + if(_hashListIterator != null){ + _listIterator.remove(); + } + + throw new UnsupportedOperationException("The iterator was not initialized."); + } + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/TimedPrjState.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/TimedPrjState.java new file mode 100644 index 000000000..00276e112 --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/TimedPrjState.java @@ -0,0 +1,458 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; + +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LpnTranList; +import edu.utah.ece.async.lema.verification.platu.project.PrjState; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.timed_state_exploration.octagon.Equivalence; +import edu.utah.ece.async.lema.verification.timed_state_exploration.octagon.Octagon; + +/** + * + * + * @author + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class TimedPrjState extends PrjState{ + + /* + * For state graph purposes, we need a unique id. Should be kept at + * the next available number. + */ + public static int TimedStateCount = 0; + + public static int getTimeStateCount(){ + return TimedStateCount; + } + + public static void incTSCount(){ + TimedStateCount++; + } + + public static void decTSCount(){ + TimedStateCount--; + } + + /* + * The id for this state. + */ + public int _tsId; + + public int getTSID(){ + return _tsId; + } + + public void setTSID(int newID){ + _tsId = newID; + } + + /** + * Sets the tsId to the current TimedStateCount. + */ + public void setCurrentId(){ + _tsId = TimedStateCount; + } + + /* + * Map states to previous state. This map needs to be maintained when + * the state graph option is selected and when supersets is enabled. + * The reason it is important for subsets is when a previously found + * state is removed due to the current state being a superset, then + * each of the states that pointed to the previous state need to + * be updated to point to the current state. + */ + private HashMap> _previousProjectState; + + /** + * Add an element to the preset. + * @param e + * @param tps + */ + public void addPreviousState(EventSet e, TimedPrjState tps){ + if (_previousProjectState.containsKey(e)){ + _previousProjectState.get(e).add(tps); + } + else{ + HashSet newSet = new HashSet(); + newSet.add(tps); + _previousProjectState.put(e, newSet); + } + } + + public HashMap> get_previousProjectState(){ + return _previousProjectState; + } + +// protected Zone[] _zones; + protected Equivalence[] _zones; + + //*public TimedPrjState(final State[] other, final Zone[] otherZones){ + //*super(other); + //*this._zones = otherZones; + //*} + public TimedPrjState(final State[] other, final Equivalence[] otherZones){ + super(other); + _tsId = TimedStateCount; + this._zones = otherZones; + if(Zone.getSupersetFlag()&&Options.getOutputSgFlag()){ + // We only need to worry about constructing this map when making the state graph. + _previousProjectState = new HashMap>(); + } + } + + + public TimedPrjState(State[] initStateArray) { + super(initStateArray); +// _zones = new Zone[initStateArray.length]; +// for(int i=0; i<_zones.length; i++){ +// _zones[i] = new Zone(initStateArray[i]); +// } + + if(Zone.getSupersetFlag()&&Options.getOutputSgFlag()){ + // We only need to worry about constructing this map when making the state graph. + _previousProjectState = new HashMap>(); + } + + if(edu.utah.ece.async.lema.verification.platu.main.Options.getTimingAnalysisType() + .equals("zone")){ + + /* + * The verification type is zones, so load the + * Equivalence variable with a zone. + */ + _zones = new Zone[1]; + + _zones[0] = new Zone(initStateArray); + } + else if (edu.utah.ece.async.lema.verification.platu.main.Options.getTimingAnalysisType() + .equals("octagon")){ + + /* + * The verification type is octagons, so load the + * Equivalence variable with an octagon. + */ + + _zones = new Octagon[1]; + + _zones[0] = new Octagon(initStateArray); + } + } + + +// public Zone[] toZoneArray(){ + public Equivalence[] toZoneArray(){ + return _zones; + } + + @Override + public boolean equals(Object other){ + if(!super.equals(other)){ + return false; + } + + if(!(other instanceof TimedPrjState)){ + return false; + } + + TimedPrjState otherTimedPrjState = (TimedPrjState) other; + + if(this._zones == otherTimedPrjState._zones){ + return true; + } + + if(!Arrays.equals(this._zones, otherTimedPrjState._zones)){ + return false; + } + + return true; + } + + @Override + public String toString(){ + String result = "TS_ID = " + _tsId + '\n'; + + result += super.toString(); + + result += "\nZones: \n"; + +// for(Zone z : _zones){ + for(Equivalence z: _zones){ + result += z.toString() + "\n"; + } + + return result; + } + + /** + * Gives the currently enabled transitions according to the given zone. + * @param zoneNumber + * The index of the Zone to consider. + * @return + * The Transitions that are enabled when considering the zone at index zoneNumber. + */ + public LpnTranList getEnabled(int zoneNumber){ + + // Zone to consider +// Zone z = _zones[zoneNumber]; + Equivalence z = _zones[zoneNumber]; + + return new LpnTranList(z.getEnabledTransitions()); + } + + /** + * Gives the Transitions belonging to a particular LPN that are enabled according to a given + * zone. + * @param zoneNumber + * The index of the zone to consider for determining the enabled transitions. + * @param lpnIndex + * The index of the LPN to which the Transitions belong. + * @return + * The Transitions in the LPN with index lpnIndex that are enabled according to the Zone + * at index zoneNumber. + */ + public LpnTranList getEnabled(int zoneNumber, int lpnIndex){ + +// Zone z = _zones[zoneNumber]; + Equivalence z = _zones[zoneNumber]; + + return new LpnTranList(z.getEnabledTransitions(lpnIndex)); + } + + /** + * Gets a project state containing the un-timed portion of this timed project state. + * @return + * A project state that has the same set of (local) un-timed states. + */ + public PrjState getUntimedPrjState(){ + return new PrjState(toStateArray()); + } + + /** + * Checks if all the zones are subsets (or equal to) the corresponding other zones as well + * as if the un-timed portions are equal. Note: it is assumed that both states have the same + * number of zones. + * @param other + * The state to compare against. + * @return + * True if zone zi is a subset of zone z'i for all i where zi is the i-th zone + * of this TimedPrjState and z'i is the i-th zone of the other TimedPrjState and + * the un-timed portion of the states are equal. + */ + public boolean subset(TimedPrjState other){ + // For clarity, extract the un-timed portions. Alternately, super.equals(otherState) would + // probably work. + + PrjState thisUntimed = this.getUntimedPrjState(); + PrjState otherUntimed = other.getUntimedPrjState(); + + if(!(thisUntimed.equals(otherUntimed))){ + return false; + } + + return subsetZone(other); + } + + /** + * Checks if all the zones are supersets (or equal to) the corresponding other zones as well + * as if the un-timed portions are equal. Note : it is assumed that both states have the same + * number of zones. + * @param other + * The state to compare against. + * @return + * True if zone zi is a superset of zone z'i for all i where zi is the i-th zone + * of this TimedPrjState and z'i is the i-th zone of the other TimedPrjState and + * the un-timed portion of the states are equal. + */ + public boolean superset(TimedPrjState other){ + // For clarity, extract the un-timed portions. Alternately, super.equals(otherState) would + // probably work. + + PrjState thisUntimed = this.getUntimedPrjState(); + PrjState otherUntimed = other.getUntimedPrjState(); + + if(!(thisUntimed.equals(otherUntimed))){ + return false; + } + + return supersetZone(other); + } + + /** + * Checks if all the zones are subsets (or equal to) the corresponding other zones. + * Note: The un-timed portion is not considered. It is assumed that each state has + * the same number of zones. + * @param other + * The state to compare against. + * @return + * True if zone zi is a subset of zone z'i for all i where zi is the i-th zone + * of this TimedPrjState and z'i is the i-th zone of the other TimedPrjState. + * False otherwise. + */ + public boolean subsetZone(TimedPrjState other){ + boolean result = true; + + for(int i=0; i + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + +/** + * + * This class is used to aid in updating continuous variables after a transition has fired. + * Its purpose is to hold the referencing information and new values for the continuous + * variable and to store information of what has changed for the continuous variable that + * will be important for updating the continuous part of the state. When a transition fires, + * it can perform a rate assignment or a value assignment to a continuous variable. + * Furthermore, variables that have a rate of zero are treated different in a Zone than those + * that have a non-zero rate. Thus it is important to know if a rate assignment results in a + * variable rate becoming zero or becoming non-zero, whether a rate assignment occurred at + * all, and whether a value assignment has occurred. + * + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class UpdateContinuous { + + /* + * Abstraction Function: An UpdateContinuous object keeps track of the referencing + * information for a variable as well as the rate and values that the variables has. + * The member variable lcrPair holds the information for referencing the variable + * in a Zone (which is often done using an LPNContinuousPair) and _value stores the + * upper and lower bounds for the continuous variable. + * + * Since Zones store rate zero variables and non-zero rate variables in different + * places, it is important to know when a variable changes from being rate zero + * to non-rate zero and vice versa. When a variable does not change between rate + * zero and a non-zero rate, then it is important to know that at least the value + * of the variable's value has changed. In addition, for variables with a non-zero, + * the rate can be change to a different non-zero rate. This leads to five + * situations. + * 1. The variable was rate zero and remains rate zero, but the value of the + * variable has changed. The field _value should contain this new value. + * 2. The variable was rate zero and now is a non-zero rate. The field _value + * contains the new value if an assignment was made and contains the old value + * if no value assignment was made. + * 3. The variable had a non-zero rate and now the rate is zero. The field _value + * contains the new value if an assignment was made and contains the old value + * if no value assignment was made. + * 4. The variable had a non-zero rate and has been assigned another non-zero rate. + * The field _value should contain the old value. + * 5. The variable had a non-zero rate and either no rate assignment has been made + * or the rate has been set to another non-zero rate and a new value has been set. + * The new value should be placed in the _value field. + * + * Note: The handling of a variable that moves between rate zero and a non-zero + * rate is not affected by a change in the value of the variable. That is the + * situation is handled the same whether the value has changed or not. Thus + * there is no need to consider the value changing separately. This not the case + * when a variable that has a non-zero rate and continues to have a non-zero rate. + * The handling is different depending on whether the value has changed or not. + */ + + /* + * Representations invariant: The field _value contains the old value for the + * variable if no value assignment was made and the contains the new value + * otherwise. + */ + + + // The rate will be set to zero. + private boolean _newZero; + + + // The rate was zero. + private boolean _oldZero; + + + // A new value was assigned. + private boolean _newValue; + + + // The rate and index for the variable. + private LPNContAndRate _lcrPair; + + + // The value. + private IntervalPair _value; + + + /** + * Creates an UpdateContinuous object that has default values of false and null. + */ + public UpdateContinuous(){ + _oldZero = false; + _newZero = false; + _newValue = false; + _value = null; + _lcrPair = null; + } + + /** + * Creates a new UpdateContinuous object with the given information for a given + * continuous variable. + * @param oldZero True if the previous rate zero; false otherwise. + * @param newZero True if the new rate is zero; false otherwise. + * @param newValue True if a value assignment has been made; false otherwise + * @param value The range of values for the continuous variable. + * @param lcrPair An LPNContAndRate pairing that has the reference information + * for the continuous variable as well as the range of rates. + */ + public UpdateContinuous(boolean oldZero, boolean newZero, boolean newValue, + IntervalPair value, LPNContAndRate lcrPair){ + _oldZero = oldZero; + _newZero = newZero; + _newValue = newValue; + _value = value; + _lcrPair = lcrPair; + } + + public UpdateContinuous(LPNContinuousPair lcpair){ + _oldZero = false; + _newZero = false; + _newValue = false; + _value = null; + _lcrPair = new LPNContAndRate(lcpair); + } + + // Getters and setters for the member variables. + + /** + * Gets whether the new rate is zero. + * + * @return True if the new rate for the variables is zero; false otherwise. + */ + public boolean is_newZero() { + return _newZero; + } + + + /** + * Sets whether the new rate is zero. + * + * @param _newZero True if the new rate is zero (regardless of the old rate); + * false otherwise. + */ + public void set_newZero(boolean _newZero) { + this._newZero = _newZero; + } + + + /** + * Gets whether the old rate is zero. + * + * @return True if the previous rate was zero; false otherwise. + */ + public boolean is_oldZero() { + return _oldZero; + } + + + /** + * Sets whether the old rate was zero. + * + * @param _oldZero True if the previous rate was zero; false otherwise. + */ + public void set_oldZero(boolean _oldZero) { + this._oldZero = _oldZero; + } + + + /** + * Gets whether the value is new or not. + * + * @return True if a new value has been assigned; false otherwise. + */ + public boolean is_newValue() { + return _newValue; + } + + + /** + * Sets whether the value is is new or not. + * + * @param _newValue True if a new value has been assigned; false otherwise. + */ + public void set_newValue(boolean _newValue) { + this._newValue = _newValue; + } + + + /** + * Gets the reference for the variable. + * + * @return The LPNContAndRate that represent the variable. + */ + public LPNContAndRate get_lcrPair() { + return _lcrPair; + } + + + /** + * Sets the reference for the variable. + * + * @param _lcrPair An LPNContAndRate that gives the reference information for + * the variable. + */ + public void set_lcrPair(LPNContAndRate _lcrPair) { + this._lcrPair = _lcrPair; + } + + + /** + * Gets the values for the variable. + * + * @return An IntervalPair that contains the upper and lower bounds for the value. + */ + public IntervalPair get_Value() { + return _value; + } + + + /** + * Sets the values for the variable. + * + * @param value An IntervalPair that contains the upper and lower bounds for the + * value. + */ + public void set_Value(IntervalPair value) { + this._value = value; + } + + + /** + * Determines if a variable was non-zero and is now zero. + * + * @return True if the previous rate was non-zero and the new rate is zero; + * false otherwise. + */ + public boolean newlyZero(){ + return !_oldZero && _newZero; + } + + /** + * Determines if a variable was zero and is now non-zero. + * + * @return True if the previous rate was zero and the new rate is non-zero; + * false otherwise. + */ + public boolean newlyNonZero(){ + return _oldZero && !_newZero; + } + + @Override + public int hashCode() { +// final int prime = 31; +// int result = 1; +// result = prime * result +// + ((_lcrPair == null) ? 0 : _lcrPair.hashCode()); +// result = prime * result + (_newValue ? 1231 : 1237); +// result = prime * result + (_newZero ? 1231 : 1237); +// result = prime * result + (_oldZero ? 1231 : 1237); +// result = prime * result + ((_value == null) ? 0 : _value.hashCode()); +// return result; + + // Two UpdateContinuous variables are the same if they share the + // same continuous part. + return _lcrPair.get_lcPair().hashCode(); + } + + + @Override + public boolean equals(Object obj) { +// if (this == obj) +// return true; +// if (obj == null) +// return false; +// if (getClass() != obj.getClass()) +// return false; +// UpdateContinuous other = (UpdateContinuous) obj; +// if (_lcrPair == null) { +// if (other._lcrPair != null) +// return false; +// } else if (!_lcrPair.equals(other._lcrPair)) +// return false; +// if (_newValue != other._newValue) +// return false; +// if (_newZero != other._newZero) +// return false; +// if (_oldZero != other._oldZero) +// return false; +// if (_value == null) { +// if (other._value != null) +// return false; +// } else if (!_value.equals(other._value)) +// return false; +// return true; + + if(!(obj instanceof UpdateContinuous)){ + return false; + } + + UpdateContinuous uc = (UpdateContinuous) obj; + + // Two UpdateContinuous objects are the same if they share the same + // continuous part. + return _lcrPair.equals(uc.get_lcrPair()); + } + + + @Override + public String toString(){ + + String s = "Variable: " + _lcrPair + "\n" + + "Was Zero: " + _oldZero + "\n" + + "Is Zero: " + _newZero + "\n" + + "New value: " + _newValue + "\n"; + + if(_value != null){ + s += "Value is:" + _value + "\n"; + } + else{ + s += "Value is null" + "\n"; + } + + return s; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/VariableRangePair.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/VariableRangePair.java new file mode 100644 index 000000000..3d128b53b --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/VariableRangePair.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + +import edu.utah.ece.async.lema.verification.lpn.Variable; + +/** + * A Variable and Range class packages an lpn.parser.Variable with an + * IntervalPair. This allows one to store the Variable along with its range. + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class VariableRangePair { + + // The variable to store. + private Variable _variable; + + + // The range of the variable. + private IntervalPair _range; + + + + public VariableRangePair(Variable _variable, IntervalPair _range) { + super(); + this._variable = _variable; + this._range = _range; + } + + + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((_variable == null) ? 0 : _variable.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof VariableRangePair)) + return false; + VariableRangePair other = (VariableRangePair) obj; + if (_variable == null) { + if (other._variable != null) + return false; + } else if (!_variable.equals(other._variable)) + return false; + return true; + } + + + + public Variable get_variable() { + return _variable; + } + + public void set_variable(Variable _variable) { + this._variable = _variable; + } + + public IntervalPair get_range() { + return _range; + } + + public void set_range(IntervalPair _range) { + this._range = _range; + } + + @Override + public String toString(){ + return "" + _variable + " = " + _range ; + } +} diff --git a/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/Zone.java b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/Zone.java new file mode 100644 index 000000000..0b7a0be8e --- /dev/null +++ b/verification/src/main/java/edu/utah/ece/async/lema/verification/timed_state_exploration/zoneProject/Zone.java @@ -0,0 +1,6890 @@ +/******************************************************************************* + * + * This file is part of iBioSim. Please visit + * for the latest version of iBioSim. + * + * Copyright (C) 2017 University of Utah + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the Apache License. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online at . + * + *******************************************************************************/ +package edu.utah.ece.async.lema.verification.timed_state_exploration.zoneProject; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import edu.utah.ece.async.lema.verification.lpn.ExprTree; +import edu.utah.ece.async.lema.verification.lpn.LPN; +import edu.utah.ece.async.lema.verification.lpn.Transition; +import edu.utah.ece.async.lema.verification.lpn.Variable; +import edu.utah.ece.async.lema.verification.platu.main.Options; +import edu.utah.ece.async.lema.verification.platu.platuLpn.DualHashMap; +import edu.utah.ece.async.lema.verification.platu.platuLpn.LpnTranList; +import edu.utah.ece.async.lema.verification.platu.stategraph.State; +import edu.utah.ece.async.lema.verification.timed_state_exploration.octagon.Equivalence; + + +/** + * This class is for storing and manipulating the delay information for transitions as well as + * the values of continuous variables including rate their rates. + * A Zone represents the non-zero continuous variables and the timers for the delay in a + * Difference Bound Matrix (DBM) + * + * t0 c0 c1 t0 t1 + * t0 m00 m01 m02 m03 m04 + * c0 m10 m11 m12 m13 m14 + * c1 m20 m21 m22 m23 m24 + * t0 m30 m31 m32 m33 m34 + * t1 m40 m41 m42 m43 m44 + * + * For the timers, tj - ti <= m(ti,tj) where m(ti,tj) represents the element of the matrix with + * row ti and column tj. In particular, m(t0,ti) is an upper bound for ti and -m(ti,0) is a + * lower bound for ti. The continuous variables are normalized to have rate one before being + * placed in the matrix. Thus for a continuous variables ci with rate ri, the entry m(t0, ci) is + * (upper bound)/ri where 'upper bound' is the upper bound for the continuous variable and + * m(ci,t0) is -1*(lower bound)/ri where 'lower bound' is the lower bound of the continuous variable. + * When the rate is negative, dividing out by the rate switches the inequalities. For example, + * if ci is a continuous variable such that l < ci < u for some values l and u, then the normalized + * ci (that is ci/ri) is satisfies u/ri < ci/r < l/ri. Hence the m(t0,ci) is (lower bound)/ri and + * m(ci,0) is -1*(upper bound)/ri. The m(ci,cj) as well as m(ti,ci) and m(ci,ti) give the same kind + * of relational information as with just timers, but with the normalized values of the continuous + * variables. Note that a Zone with normalized continuous variables is referred to as being a 'warped' + * zone. + * + * The rate zero continuous variables are also stored in a Zone object, but they are not present in + * the zone. The Zone merely records the range of the continuous variable. + * + * The timers are referenced by the name of the transition that they are associated with and continuous + * variables are referenced by their name as well. In addition for non-zero rate continuous variables and + * the timers, several method will allow them to be referred by their index as a part of the (DMB). For + * example, c0 in the above DBM example, has index 1. + * + * A third way that the timers and variables (both rate zero and rate non-zero) can be referred to by + * an LPNTransitionPair object. These objects refer to a timer or continuous variable by providing the index + * of the corresponding transition or the index of the continuous variable as a member of an LPN and the + * index of that LPN. The LPNTransitionPair can be made more specific in the case of the continuous variables + * by using an LPNContinuousPair. These objects also provide the rate of the variable. LPNTransitionPairs + * can be used with continuous variables when they are only being used as an index only. If the rate is needed + * for the method, then LPNContinuousPairs must be used. + * + * @author Andrew N. Fisher + * @author Chris Myers + * @author iBioSim Contributors + * @version %I% + */ +public class Zone implements Equivalence{ + + /*Abstraction Function : + * The difference bound matrix is stored in the _matrix member field, along with + * the upper and lower bounds of the timers and rates for continuous variables. + * The upper and lower bounds are stored when the timer becomes enabled. The upper and + * lower bounds of the rates are stored when the rate is assigned. The upper and lower + * bounds are stored in the first row and first column of the _matrix member field. + * The DBM occupies the rest of the array, that is, the sub-array formed by removing + * the first column and first row. + * For example, let t1 be a timer for a transition whose delay is between 2 and 3. Further + * let c1 be a continuous variable with rate between 4 and 5. Then _matrix would look like + * lb t0 c1 t1 + * ub x 0 5 3 + * t0 0 m m m + * c1 -4 m m m + * t1 -2 m m m + * + * with out the lb, ub, t0, t1, and c1. + * + * The x is does not represent anything and will most likely be zero. The upper and lower + * bounds for the zero timer (which is always present) are always 0. The m's comprise + * the DBM. + * + * For the most part, a timer or a continuous variable is referred to internally by an + * LPNTransitionPair. An LPNTransitionPair combines the index of the transition (or + * continuous variable) with the index of the LPN that the transition (or continuous + * variables) is a member of. Both continuous variables and transitions can be referred + * to by an LPNTransitionPair; however, it is better to use an LPNContinuousPair (which + * is inherited from the LPNTransitionPair) to refer to continuous variables. + * LPNContinuousPairs are used to distinguish continuous variables from transitions. They + * also store the current rate of the continuous variable. + * + * The LPNTransitionPairs are stored in the _indexToTimerPair member field. The row/column + * in the DBM for a transition is determined by the its position in this array. For example, + * suppose a transition t has an LPNTransitionPair ltTranPair that is the third element of + * the _indexToTimerPair. Then t will be the third column/row of the DBM. + * + * Continuous variables are handled slightly differently. The LPNContinuousPair for the + * continuous variables with a non-zero rate are stored in the _indexToTimerPair just as + * with the transitions. And just like with the transitions, the index in the DBM is + * determined by the index of the LPNContinuousPair in the _indexToTimerPair. However, + * rate zero continuous variables are stored in the _rateZeroContinuous member variable. + * The _rateZerContinuous pairs an LPNContinuousPair with a VariableRangePair. The + * VariableRangePair combines the variable with its upper and lower bound. + * + */ + + /* Representation invariant : + * Zones are immutable. + * Integer.MAX_VALUE is used to logically represent infinity. + * The lb and ub values for a timer should be set when the timer is enabled. + * A negative hash code indicates that the hash code has not been set. + * The index of the timer in _indexToTimer is the index in the DBM and should contain + * the zeroth timer. + * The array _indexToTimerPair should always be sorted. + * The index of the LPN should match where it is in the _lpnList, that is, if lpn is + * and LhpnFile object in _lpnList, then _lpnList[getLpnIndex()] == lpn. + * The LPNTransitionPair in the _indexToTimer array should be an LPNContinuousPair + * when it stores the index to a continuous variable. Testing that the index + * is an LPNContinuousPair is used to determined if the indexing object points + * to a continuous variable. Also the LPNContinuousPair keeps track of the current rate. + * + */ + + /* + * Resource List : + * TODO : Create a list reference where the algorithms can be found that this class + * depends on. + */ + + public static final int INFINITY = Integer.MAX_VALUE; + + /* The lower and upper bounds of the times as well as the dbm. */ + private int[][] _matrix; + + /* Maps the index to the timer. The index is row/column of the DBM sub-matrix. + * Logically the zero timer is given index -1. + * */ + //private int[] _indexToTimer; + + private LPNTransitionPair[] _indexToTimerPair; + + /* The hash code. */ + private int _hashCode; + + /* A lexicon between a transitions index and its name. */ + //private static HashMap _indexToTransition; + + /* Set if a failure in the testSplit method has fired already. */ + //private static boolean _FAILURE = false; + + /* Hack to pass a parameter to the equals method though a variable */ + //private boolean subsetting = false; + + /* Stores the continuous variables that have rate zero */ +// HashMap _rateZeroContinuous; + //DualHashMap _rateZeroContinuous; + DualHashMap _rateZeroContinuous; + + /* Records the largest zone that occurs. */ + public static int ZoneSize = 0; + + /* Write a log file */ + private static BufferedWriter _writeLogFile = null; + + /** + * Returns the write log. + * @return + * The _writeLogfile. + */ + public static BufferedWriter get_writeLogFile(){ + return _writeLogFile; + } + + /** + * Sets the BufferedWriter. + * @param writeLogFile + */ + public static void set_writeLogFile(BufferedWriter writeLogFile){ + _writeLogFile = writeLogFile; + } + + /** + * Sets the writeLogFile to null. + */ + public static void reset_writeLogFile(){ + _writeLogFile = null; + } + + private void checkZoneMaxSize(){ + if(dbmSize() > ZoneSize){ + ZoneSize = dbmSize(); + } + } + + private LPN[] _lpnList; + + /* + * Turns on and off subsets for the zones. + * True means subset will be considered. + * False means subsets will not be considered. + */ + private static boolean _subsetFlag = true; + + /* + * Turns on and off supersets for zones. + * True means that supersets will be considered. + * False means that supersets will not be considered. + */ + private static boolean _supersetFlag = true; + + + /** + * Gets the value of the subset flag. + * @return + * True if subsets are requested, false otherwise. + */ + public static boolean getSubsetFlag(){ + return _subsetFlag; + } + + /** + * Sets the value of the subset flag. + * @param useSubsets + * The value for the subset flag. Set to true if + * supersets are to be considered, false otherwise. + */ + public static void setSubsetFlag(boolean useSubsets){ + _subsetFlag = useSubsets; + } + + /** + * Gets the value of the superset flag. + * @return + * True if supersets are to be considered, false otherwise. + */ + public static boolean getSupersetFlag(){ + return _supersetFlag; + } + + /** + * Sets the superset flag. + * @param useSupersets + * The value of the superset flag. Set to true if + * supersets are to be considered, false otherwise. + */ + public static void setSupersetFlag(boolean useSupersets){ + _supersetFlag = useSupersets; + } + + /** + * Construct a zone that has the given timers. + * @param timers + * The ith index of the array is the index of the timer. For example, + * if timers = [1, 3, 5], then the zeroth row/column of the DBM is the + * timer of the transition with index 1, the first row/column of the + * DBM is the timer of the transition with index 3, and the 2nd + * row/column is the timer of the transition with index 5. Do not + * include the zero timer. + * @param matrix + * The DBM augmented with the lower and upper bounds of the delays for the + * transitions. For example, suppose a zone has timers [1, 3, 5] (as + * described in the timers parameters). The delay for transition 1 is + * [1, 3], the delay for transition 3 is [2,5], and the delay for + * transition 5 is [4,6]. Also suppose the DBM is + * t0 t1 t3 t5 + * t0 | 0, 3, 3, 3 | + * t1 | 0, 0, 0, 0 | + * t3 | 0, 0, 0, 0 | + * t5 | 0, 0, 0, 0 | + * Then the matrix that should be passed is + * lb t0 t1 t3 t5 + * ub| 0, 0, 3, 5, 6| + * t0| 0, 0, 3, 3, 3| + * t1|-1, 0, 0, 0, 0| + * t3|-2, 0, 0, 0, 0| + * t5|-4, 0, 0, 0, 0| + * The matrix should be non-null and the zero timer should always be the + * first timer, even when there are no other timers. + */ + public Zone(int[] timers, int[][] matrix) + { + // A negative number indicates that the hash code has not been set. + _hashCode = -1; + + // Make a copy to reorder the timers. +// _indexToTimer = Arrays.copyOf(timers, timers.length); + + // Make a copy to reorder the timers. + _indexToTimerPair = new LPNTransitionPair[timers.length]; + for(int i=0; i 0) +// { +// int[] newTimerIndex = new int[_indexToTimer.length+1]; +// for(int i=0; i<_indexToTimer.length; i++) +// { +// newTimerIndex[i+1] = _indexToTimer[i]; +// } +// } + + // Map the old index of the timer to the new index of the timer. + HashMap newIndex = new HashMap(); + + // For the old index, find the new index. + for(int i=0; i enabledTransitionsArrayList = + new ArrayList(); + +// LPNTransitionPair zeroPair = new LPNTransitionPair(LPNTransitionPair.ZERO_TIMER, -1); + LPNTransitionPair zeroPair = new LPNTransitionPair(LPNTransitionPair.ZERO_TIMER, + LPNTransitionPair.ZERO_TIMER); + + // Add the zero timer first. + enabledTransitionsArrayList.add(zeroPair); + + // The index of the boolean value corresponds to the index of the Transition. + for(int i=0; i varValues = + lpn.getAllVarsWithValuesAsString(initialState.getVariableVector()); + + // Set the upper and lower bound. + int upper, lower; + if(delay.getOp().equals("uniform")) + { + ExprTree lowerDelay = delay.getLeftChild(); + ExprTree upperDelay = delay.getRightChild(); + + lower = (int) lowerDelay.evaluateExpr(varValues); + upper = (int) upperDelay.evaluateExpr(varValues); + } + else + { + lower = (int) delay.evaluateExpr(varValues); + + upper = lower; + } + + setLowerBoundbydbmIndex(i, lower); + setUpperBoundbydbmIndex(i, upper); + } + + // Advance the time and tighten the bounds. + advance(); + recononicalize(); + + checkZoneMaxSize(); + } + + /** + * Creates a Zone based on the local states. + * @param localStates + * The current state (or initial) of the LPNs. + */ + public Zone(State[] localStates){ + + // Open the log file. + if(_writeLogFile == null && Options.get_TimingLogfile() != null){ + try{ + _writeLogFile = + new BufferedWriter( + new FileWriter(Options.get_TimingLogfile())); + } catch (IOException e) { + + e.printStackTrace(); + }finally{ + + } + } + + // Initialize hash code to -1 (indicating nothing cached). + _hashCode = -1; + + // Initialize the LPN list. + initialize_lpnList(localStates); + + // Get the enabled transitions. This initializes the _indexTotimerPair + // which stores the relevant information. + // This method will also initialize the _rateZeroContinuous + initialize_indexToTimerPair(localStates); + + // Initialize the matrix. + _matrix = new int[matrixSize()][matrixSize()]; + + // Set the lower bound/ upper bounds of the timers and the rates. + initializeLowerUpperBounds(getAllNames(), localStates); + + // Initialize the row and column entries for the continuous variables. + initializeRowColumnContVar(); + + // Create a previous zone to the initial zone for the sake of warping. + Zone tmpZone = beforeInitialZone(); + + dbmWarp(tmpZone); + + recononicalize(); + + // Advance Time + //advance(); + advance(localStates); + + // Re-canonicalize + recononicalize(); + + // Check the size of the DBM. + checkZoneMaxSize(); + } + + /** + * Creates a Zone based on the local states. + * @param localStates + * The current state (or initial) of the LPNs. + */ + public Zone(State[] localStates, boolean init){ + + // Extract the local states. + //State[] localStates = tps.toStateArray(); + + // Initialize hash code to -1 (indicating nothing cached). + _hashCode = -1; + + // Initialize the LPN list. + initialize_lpnList(localStates); + + // Get the enabled transitions. This initializes the _indexTotimerPair + // which stores the relevant information. + // This method will also initialize the _rateZeroContinuous + initialize_indexToTimerPair(localStates); + + // Initialize the matrix. + _matrix = new int[matrixSize()][matrixSize()]; + + // Set the lower bound/ upper bounds of the timers and the rates. + initializeLowerUpperBounds(getAllNames(), localStates); + + // Initialize the row and column entries for the continuous variables. + initializeRowColumnContVar(); + + if(init){ + return; + } + + // Advance Time + //advance(); + advance(localStates); + + // Re-canonicalize + recononicalize(); + + // Check the size of the DBM. + checkZoneMaxSize(); + } + +// /** +// * Sets ups a zone containing continuous variables only. +// * @param continuousValues +// * The values to populate the zone with. +// */ +// public Zone(HashMap continuousValues){ +// +// Set pairSet = continuousValues.keySet(); +// +// // Copy the LPNContinuousPairs over +// _indexToTimerPair = new LPNTransitionPair[pairSet.size()+1]; +// +// int count = 0; // The position in the _indexToTimerPair for the next value. +// _indexToTimerPair[count++] = LPNTransitionPair.ZERO_TIMER_PAIR; +// +// for(LPNContinuousPair lcPair: pairSet){ +// _indexToTimerPair[count++] = lcPair; +// } +// +// Arrays.sort(_indexToTimerPair); +// +// _matrix = new int[matrixSize()][matrixSize()]; +// +// for(int i=1; i contNames = new ArrayList(); + + // Find the pairs that represent the continuous variables. Loop starts at + // i=1 since the i=0 is the zero timer. + for(int i=1; i<_indexToTimerPair.length; i++){ + + LPNTransitionPair ltPair = _indexToTimerPair[i]; + + // If the isTimer value is false, then this pair represents a continuous + // variable. + //if(!ltPair.get_isTimer()){ + // If pair is LPNContinuousPair. + if(ltPair instanceof LPNContinuousPair){ + // Get the LPN that this pairing references and find the name of + // the continuous variable whose index is given by this pairing. + contNames.add(_lpnList[ltPair.get_lpnIndex()] + .getContVarName(ltPair.get_transitionIndex())); + } + } + + return contNames.toArray(new String[0]); + } + + /** + * Gets the names of the transitions that are associated with the timers in the + * zone. Does not return the zero timer. + * @return + * The names of the transitions whose timers are in the zone except the zero + * timer. + */ + public String[] getTranNames(){ + + // List for accumulating the names. + ArrayList transitionNames = new ArrayList(); + + // Find the pairs that represent the transition timers. + for(int i=1; i<_indexToTimerPair.length; i++){ + + LPNTransitionPair ltPair = _indexToTimerPair[i]; + + // If the isTimer value is true, then this pair represents a timer. + //if(ltPair.get_isTimer()){ + // If this is an LPNTransitionPair and not an LPNContinuousPair + if(!(ltPair instanceof LPNContinuousPair)){ + // Get the LPN that this pairing references and find the name of the + // transition whose index is given by this pairing. + transitionNames.add(_lpnList[ltPair.get_lpnIndex()] + .getTransition(ltPair.get_transitionIndex()).getLabel()); + } + } + + return transitionNames.toArray(new String[0]); + } + + /** + * Initializes the _lpnList using information from the local states. + * @param localStates + * The local states. + * @return + * The enabled transitions. + */ + private void initialize_lpnList(State[] localStates){ + + // Create the LPN list. + _lpnList = new LPN[localStates.length]; + + // Get the LPNs. + for(int i=0; i(); + + // This list accumulates the transition pairs (ie timers) and the continuous + // variables. + ArrayList enabledTransitionsArrayList = + new ArrayList(); + + // Put in the zero timer. +// enabledTransitionsArrayList +// .add(new LPNTransitionPair(LPNTransitionPair.ZERO_TIMER, -1)); + enabledTransitionsArrayList + .add(new LPNTransitionPair(LPNTransitionPair.ZERO_TIMER, + LPNTransitionPair.ZERO_TIMER)); + + // Get the continuous variables. + for(int i=0; i singleLPN = + new ArrayList(); + + // Get the associated LPN. + LPN lpn = localStates[i].getLpn(); + + // Get the continuous variables for this LPN. + String[] continuousVariables = lpn.getContVars(); + + // Get the variable, index map. + DualHashMap variableIndex = lpn.getContinuousIndexMap(); + + // Find which have a nonzero rate. + for(int j=0; j singleLPN = new ArrayList(); + + // The index of the boolean value corresponds to the index of the Transition. + for(int j=0; j varValues = + _lpnList[ltPair.get_lpnIndex()] + .getAllVarsWithValuesAsString(localStates[ltPair.get_lpnIndex()].getVariableVector()); + + // Set the upper and lower bound. + // Passing the zone as null since it should not be needed. +// if(delay.getOp().equals("uniform")){ +// IntervalPair lowerRange = delay.getLeftChild() +// .evaluateExprBound(varValues, null); +// IntervalPair upperRange = delay.getRightChild() +// .evaluateExprBound(varValues, null); +// +// // The lower and upper bounds should evaluate to a single +// // value. Yell if they don't. +// if(!lowerRange.singleValue() || !upperRange.singleValue()){ +// throw new IllegalStateException("When evaulating the delay, " + +// "the lower or the upper bound evaluated to a range " + +// "instead of a single value."); +// } +// +// range = new IntervalPair(lowerRange.get_LowerBound(), +// upperRange.get_UpperBound()); +// +// } +// else{ +// range = delay.evaluateExprBound(varValues, null); +// } + + if (delay!=null) { + range = delay.evaluateExprBound(varValues, this, null); + } else { + range = new IntervalPair(0,0); + } +// int upper, lower; +// if(delay.getOp().equals("uniform")) +// { +// ExprTree lowerDelay = delay.getLeftChild(); +// ExprTree upperDelay = delay.getRightChild(); +// +// lower = (int) lowerDelay.evaluateExpr(varValues); +// upper = (int) upperDelay.evaluateExpr(varValues); +// } +// else +// { +// lower = (int) delay.evaluateExpr(varValues); +// +// upper = lower; +// } + } +// setLowerBoundbydbmIndex(i, lower); +// setUpperBoundbydbmIndex(i, upper); + + setLowerBoundbydbmIndex(i, range.get_LowerBound()); + setUpperBoundbydbmIndex(i, range.get_UpperBound()); + } + + } + + /** + * Initialize the rows and columns for the continuous variables. + */ + private void initializeRowColumnContVar(){ + + /* + * TODO : Describe the idea behind the following algorithm. + */ + +// for(int row=2; row<_indexToTimerPair.length; row++){ +// // Note: row is indexing the row of the DBM matrix. +// +// LPNTransitionPair ltRowPair = _indexToTimerPair[row]; +// +// if(ltRowPair.get_isTimer()){ +// // If we reached the timers, stop. +// break; +// } +// +// for(int col=1; col(); + } + + /** + * Gets the upper bound of a Transition from the zone. + * @param t + * The transition whose upper bound is wanted. + * @return + * The upper bound of Transition t. + */ + public int getUpperBoundbyTransition(Transition t) + { + LPN lpn = t.getLpn(); + + int lpnIndex = lpn.getLpnIndex(); + + int transitionIndex = t.getIndex(); + +// LPNTransitionPair ltPair = +// new LPNTransitionPair(lpnIndex, transitionIndex, true); + LPNTransitionPair ltPair = + new LPNTransitionPair(lpnIndex, transitionIndex); + + return getUpperBoundbydbmIndex(Arrays.binarySearch(_indexToTimerPair, ltPair)); + } + + /** + * Returns the upper bound of the continuous variable. + * @param var + * The variable of interest. + * @return + * The (0,var) entry of the zone, that is the maximum as recored by + * the zone. + */ + public int getUpperBoundbyContinuousVariable(String contVar, LPN lpn){ + + // TODO : Finish. + +// // Determine whether the variable is in the zone or rate zero. +// RangeAndPairing indexAndRange = _rateZeroContinuous.getKey(var); +// +// +// // If a RangeAndPairing is returned, then get the information from here. +// if(indexAndRange != null){ +// return indexAndRange.get_range().get_UpperBound(); +// } +// +// // If indexAndRange is null, then try to get the value from the zone. +// int i=-1; +// for(i=0; i<_indexToTimerPair.length; i++){ +// if(_indexToTimerPair[i].equals(var)){ +// break; +// } +// } +// +// if(i < 0){ +// throw new IllegalStateException("Atempted to find the upper bound for " +// + "a non-rate zero continuous variable that was not found in the " +// + "zone."); +// } +// +// return getUpperBoundbydbmIndex(i); + + // Extract the necessary indecies. + int lpnIndex = lpn.getLpnIndex(); + + //int contVarIndex = lpn.get + DualHashMap variableIndecies = lpn.getContinuousIndexMap(); + int contIndex = variableIndecies.get(contVar); + + // Package the indecies with false indicating not a timer. +// LPNTransitionPair index = new LPNTransitionPair(lpnIndex, contIndex, false); + // Note : setting the rate is not necessary here since this is only + // being used as an index. +// LPNContinuousPair index = new LPNContinuousPair(lpnIndex, contIndex, 0); + LPNContinuousPair index = new LPNContinuousPair(lpnIndex, contIndex); + + //Search for the continuous variable in the rate zero variables. + VariableRangePair pairing = _rateZeroContinuous.get(index); + + // If Pairing is not null, the variable was found and return the result. + if(pairing != null){ + return pairing.get_range().get_UpperBound(); + } + + // If Pairing was null, the variable was not found. Search for the variable + // in the zone portion. + int i = Arrays.binarySearch(_indexToTimerPair, index); + + // If i < 0, the search was unsuccessful, so scream. + if(i < 0){ + throw new IllegalArgumentException("Atempted to find the lower bound for " + + "a non-rate zero continuous variable that was not found in the " + + "zone."); + } + + //return getUpperBoundbydbmIndex(i); + return getDbmEntry(0, i); + } + + public int getUpperBoundForRate(LPNTransitionPair contVar){ + // TODO : finish. + + // Check if the contVar is in the zone. + int i = Arrays.binarySearch(_indexToTimerPair, contVar); + + if(i > 0){ + // The continuous variable is in the zone. + // The upper and lower bounds are stored in the same + // place as the delays, so the same method of + // retrieval will work. + //return getUpperBoundbydbmIndex(contVar.get_transitionIndex()); + + // Grab the current rate from the LPNContinuousPair. + return ((LPNContinuousPair)_indexToTimerPair[i]).getCurrentRate(); + } + + + // Assume the rate is zero. This covers the case if conVar + // is in the rate zero as well as if its not in the state at all. + return 0; + } + + /** + * Get the value of the upper bound for the delay. If the index refers + * to a timer, otherwise get the upper bound for the continuous + * variables rate. + * @param index + * The timer's row/column of the DBM matrix. + * @return + * The upper bound on the transitions delay. + */ + public int getUpperBoundbydbmIndex(int index) + { + return _matrix[0][dbmIndexToMatrixIndex(index)]; + } + + + public int getUpperBound(int index){ + return _matrix[0][dbmIndexToMatrixIndex(index)]; + } + + @Override + public int getUpperBoundTrue(int index){ + return _matrix[dbmIndexToMatrixIndex(0)] + [dbmIndexToMatrixIndex(index)]; + } + + public int getUnwarpedUpperBound(LPNContinuousPair lcpair){ + // Get the index. + int index = Arrays.binarySearch(_indexToTimerPair, lcpair); + + int rate = ((LPNContinuousPair) _indexToTimerPair[index]) + .getCurrentRate(); + + int warpValue = getUpperBoundTrue(index); + + return warpValue * rate; + } + + public int getLowerBound(int index){ + return _matrix[dbmIndexToMatrixIndex(index)][0]; + } + + @Override + public int getLowerBoundTrue(int index){ + return _matrix[dbmIndexToMatrixIndex(index)] + [dbmIndexToMatrixIndex(0)]; + } + + /** + * Set the value of the upper bound for the delay. + * @param t + * The transition whose upper bound is being set. + * @param value + * The value of the upper bound. + */ + public void setUpperBoundbyTransition(Transition t, int value) + { + LPN lpn = t.getLpn(); + + int lpnIndex = lpn.getLpnIndex(); + + int transitionIndex = t.getIndex(); + +// LPNTransitionPair ltPair = new LPNTransitionPair(lpnIndex, transitionIndex, true); + LPNTransitionPair ltPair = new LPNTransitionPair(lpnIndex, transitionIndex); + + setUpperBoundbydbmIndex(Arrays.binarySearch(_indexToTimerPair, ltPair), value); + } + + /** + * Set the value of the upper bound for the delay. + * @param index + * The timer's row/column of the DBM matrix. + * @param value + * The value of the upper bound. + */ + public void setUpperBoundbydbmIndex(int index, int value) + { + _matrix[0][dbmIndexToMatrixIndex(index)] = value; + } + + /** + * Sets the upper bound for a transition described by an LPNTransitionPair. + * @param ltPair + * The index of the transition and the index of the associated LPN for + * the timer to set the upper bound. + * @param value + * The value for setting the upper bound. + */ + private void setUpperBoundByLPNTransitionPair(LPNTransitionPair ltPair, int value){ + + setUpperBoundbydbmIndex(Arrays.binarySearch(_indexToTimerPair, ltPair), value); + } + + /** + * Gets the lower bound of a Transition from the zone. + * @param t + * The transition whose upper bound is wanted. + * @return + * The lower bound of Transition t. + */ + @Override + public int getLowerBoundbyTransition(Transition t) + { + LPN lpn = t.getLpn(); + + int lpnIndex = lpn.getLpnIndex(); + + int transitionIndex = t.getIndex(); + +// LPNTransitionPair ltPair = new LPNTransitionPair(lpnIndex, transitionIndex, true); + LPNTransitionPair ltPair = new LPNTransitionPair(lpnIndex, transitionIndex); + + return getLowerBoundbydbmIndex( + Arrays.binarySearch(_indexToTimerPair, ltPair)); + } + + /** + * Returns the lower bound of the continuous variable. + * @param var + * The variable of interest. + * @return + * The (0,var) entry of the zone, that is the minimum as recored by + * the zone. + */ + public int getLowerBoundbyContinuousVariable(String contVar, LPN lpn){ + + // Extract the necessary indecies. + int lpnIndex = lpn.getLpnIndex(); + + //int contVarIndex = lpn.get + DualHashMap variableIndecies = lpn.getContinuousIndexMap(); + int contIndex = variableIndecies.get(contVar); + + // Package the indecies with false indicating not a timer. +// LPNTransitionPair index = new LPNTransitionPair(lpnIndex, contIndex, false); + // Note: Setting the rate is not necessary since this is only being used + // as an index. +// LPNContinuousPair index = new LPNContinuousPair(lpnIndex, contIndex, 0); + LPNContinuousPair index = new LPNContinuousPair(lpnIndex, contIndex); + + //Search for the continuous variable in the rate zero variables. + VariableRangePair pairing = _rateZeroContinuous.get(index); + + // If Pairing is not null, the variable was found and return the result. + if(pairing != null){ + return pairing.get_range().get_LowerBound(); + } + + // If Pairing was null, the variable was not found. Search for the variable + // in the zone portion. + int i = Arrays.binarySearch(_indexToTimerPair, index); + + // If i < 0, the search was unsuccessful, so scream. + if(i < 0){ + throw new IllegalArgumentException("Atempted to find the lower bound for " + + "a non-rate zero continuous variable that was not found in the " + + "zone."); + } + + //return getLowerBoundbydbmIndex(i); + return getDbmEntry(i, 0); + } + + /** + * Get the value of the lower bound for the delay if the index refers + * to a timer, otherwise get the lower bound for the continuous variables + * rate. + * @param index + * The timer's row/column of the DBM matrix. + * @return + * The value of the lower bound. + */ + public int getLowerBoundbydbmIndex(int index) + { + return _matrix[dbmIndexToMatrixIndex(index)][0]; + } + + public int getLowerBoundForRate(LPNTransitionPair contVar){ + // TODO : finish. + + + // Check if the contVar is in the zone. + int i = Arrays.binarySearch(_indexToTimerPair, contVar); + + if(i > 0){ + // The continuous variable is in the zone. + // The upper and lower bounds are stored in the same + // place as the delays, so the same method of + // retrieval will work. + return getLowerBoundbydbmIndex(contVar.get_transitionIndex()); + } + + + // Assume the rate is zero. This covers the case if conVar + // is in the rate zero as well as if its not in the state at all. + return 0; + } + + /** + * Set the value of the lower bound for the delay. + * @param t + * The transition whose lower bound is being set. + * @param value + * The value of the lower bound. + */ + public void setLowerBoundbyTransition(Transition t, int value) + { + LPN lpn = t.getLpn(); + + int lpnIndex = lpn.getLpnIndex(); + + int transitionIndex = t.getIndex(); + +// LPNTransitionPair ltPair = new LPNTransitionPair(lpnIndex, transitionIndex, true); + LPNTransitionPair ltPair = new LPNTransitionPair(lpnIndex, transitionIndex); + + setLowerBoundbydbmIndex(Arrays.binarySearch(_indexToTimerPair,ltPair), value); + } + + /** + * Set the value of the lower bound for the delay. + * @param t + * The transition whose upper bound is being set. + * @param value + * The value of the upper bound. + */ + private void setLowerBoundByLPNTransitionPair(LPNTransitionPair ltPair, int value){ + setLowerBoundbydbmIndex(Arrays.binarySearch(_indexToTimerPair,ltPair), value); + } + + /** + * Set the value of the lower bound for the delay. + * @param index + * The timer's row/column of the DBM matrix. + * @param value + * The value of the lower bound. + */ + public void setLowerBoundbydbmIndex(int index, int value) + { + _matrix[dbmIndexToMatrixIndex(index)][0] = -1*value; + } + + /** + * Give the upper and lower bounds for a continuous variable. + * @param contVar + * The variable of interest. + * @return + * The upper and lower bounds according to the Zone. + */ + @Override + public IntervalPair getContinuousBounds(String contVar, LPN lpn){ + + /* + * Need to determine whether this is suppose to be a rate zero variable or a non-zero + * rate variable. One method is to check the rate of the passed variable. The other is + * to just check if the variable is present in either place. + */ + + // Extract the necessary indecies. + int lpnIndex = lpn.getLpnIndex(); + + // Get the index of the continuous variable. + DualHashMap variableIndecies = lpn.getContinuousIndexMap(); + int contIndex = variableIndecies.get(contVar); + + // Package the indecies with false indicating not a timer. +// LPNTransitionPair index = new LPNTransitionPair(lpnIndex, contIndex, false); + // Note: setting the current rate is not necessary here since the + // LPNContinuousPair is only being used as an index. +// LPNContinuousPair index = new LPNContinuousPair(lpnIndex, contIndex, 0); + LPNContinuousPair index = new LPNContinuousPair(lpnIndex, contIndex); + + // Search for the continuous variable in the rate zero variables. + VariableRangePair pairing = _rateZeroContinuous + .get(new LPNContAndRate(index, new IntervalPair(0,0))); + + // If Pairing is not null, the variable was found and return the result. + if(pairing != null){ + return pairing.get_range(); + } + + // If Pairing was null, the variable was not found. Search for the variable + // in the zone portion. + int i = Arrays.binarySearch(_indexToTimerPair, index); + + // If i < 0, the search was unsuccessful, so scream. + if(i < 0){ + throw new IllegalArgumentException("Atempted to find the bounds for " + + "a non-rate zero continuous variable that was not found in the " + + "zone."); + } + + // Else find the upper and lower bounds. +// int lower = getLowerBoundbydbmIndex(i); +// int upper = getUpperBoundbydbmIndex(i); + + int lower = (-1)*getDbmEntry(i, 0); + int upper = getDbmEntry(0, i); + + return new IntervalPair(lower, upper); + } + + /** + * Gets the range for the continuous variable. Values come back not + * warped. + * @param ltContPair + * The index of the variable of interest. + * @return + * The range of the continuous variable described by ltContPair. + */ + @Override + public IntervalPair getContinuousBounds(LPNContinuousPair ltContPair){ + + // First check in the zone. + int variableIndex = Arrays.binarySearch(_indexToTimerPair, ltContPair); + + if(variableIndex < 0){ + // The variable was not found in the zone. Check to see if its + // in the rate-zero variables. Technically I will return whatever + // is in the _rateZeroConintuous, null or not. +// return _rateZeroContinuous.get(ltContPair).get_range(); + + // First get an object to reference into the _rateZeroContinuous + LPNContAndRate lcr = new LPNContAndRate(ltContPair, + new IntervalPair(0,0)); + return _rateZeroContinuous.get(lcr).get_range(); + } + + // The variable was found in the zone. Yay. + int lower = (-1)*getDbmEntry(variableIndex, 0) + *getCurrentRate(ltContPair); + int upper = getDbmEntry(0, variableIndex) + *getCurrentRate(ltContPair); + + // If the current rate is negative the upper and lower bounds + // need to be switched. + if(getCurrentRate(ltContPair) < 0 ){ + int tmp = lower; + lower = upper; + upper = tmp; + } + + return new IntervalPair(lower, upper); + } + + /** + * Gets the range of the rate associated with a continuous variable. + * @param ltContPair + * The index of the continuous variable. + * @return + * The range of rates associated with the continuous variable indexed + * by ltContPair. + */ + @Override + public IntervalPair getRateBounds(LPNTransitionPair ltPair){ + + int upper; + int lower; + + // Check if the ltContpair is in the zone. + int i = Arrays.binarySearch(_indexToTimerPair, ltPair); + + if(i < 0){ + // Then the variable is in the rate zero continuous + // variables so get the range of rates from there. +// return new IntervalPair(0,0); + + // Create an object to reference into the rate zero. + LPNContAndRate lcr = + new LPNContAndRate((LPNContinuousPair) ltPair, + new IntervalPair(0,0)); + + // Get the old version of lcr from the rate zero since + // that contains the rate. This is quite a hack. + VariableRangePair vrp = _rateZeroContinuous.get(lcr); + lcr = _rateZeroContinuous.getKey(vrp); + + return lcr.get_rateInterval(); + } + + + upper = getUpperBoundbydbmIndex(i); + lower = -1*getLowerBoundbydbmIndex(i); + + + // The continuous variable is in the zone. + // The upper and lower bounds are stored in the same + // place as the delays, so the same method of + // retrieval will work. + return new IntervalPair(lower, upper); + } + + /** + * Gets the rate reset value. + * @param ltPair + * @return + */ + @Override + public int rateResetValue(LPNTransitionPair ltPair){ + + IntervalPair rateBounds = getRateBounds(ltPair); + + int upper = rateBounds.get_UpperBound(); + int lower = rateBounds.get_LowerBound(); + + + +// // Check if the ltContpair is in the zone. +// int i = Arrays.binarySearch(_indexToTimerPair, ltPair); +// +// if(i < 0){ +// // Assume the rate is zero. This covers the case if conVar +// // is in the rate zero as well as if its not in the state at all. +// return 0; +// } +// +// +// upper = getUpperBoundbydbmIndex(i); +// lower = -1*getLowerBoundbydbmIndex(i); + + + // If zero is a possible rate, then it is the rate to set to. +// if( lower < 0 && upper > 0){ +// return 0; +// } + +// // If zero is the only possible rate, return that. +// if(lower == upper){ +// return lower; +// } +// +// // When zero is in the range and there is a positive rate, return the +// // positive rate. +// if(lower == 0 || (lower < 0 && upper >0)){ +// return upper; +// } +// +// // When the upper bound is zero, return the negative rate. +// if(upper == 0){ +// return lower; +// } +// +// // When zero is not present, use the smallest rate in absolute value. +// return Math.abs(lower)=0, we set the rate to b. + * If b<=0, we set the rate to a. Otherwise, a<00)){ +// return upper; +// } +// +// // When the upper bound is zero, return the negative rate. +// if(upper == 0){ +// return lower; +// } +// +// // When zero is not present, use the smallest rate in absolute value. +// return Math.abs(lower)=0, we set the rate to b. + * If b<=0, we set the rate to a. Otherwise, a<0 variableIndecies = lpn.getContinuousIndexMap(); + int contIndex = variableIndecies.get(contVar); + + // Package the indecies with false indicating not a timer. +// LPNTransitionPair index = new LPNTransitionPair(lpnIndex, contIndex, false); + //Note : Setting the rate is not necessary since this only being used + // as an index. +// LPNContinuousPair index = new LPNContinuousPair(lpnIndex, contIndex, 0); + LPNContinuousPair index = new LPNContinuousPair(lpnIndex, contIndex); + + // Search for the continuous variable in the rate zero variables. + VariableRangePair pairing = _rateZeroContinuous.get(index); + + // If Pairing is not null, the variable was found and make the new assignment. + if(pairing != null){ + pairing.set_range(range); + return; + } + + // If Pairing was null, the variable was not found. Search for the variable + // in the zone portion. + int i = Arrays.binarySearch(_indexToTimerPair, index); + + // If i < 0, the search was unsuccessful, so scream. + if(i < 0){ + throw new IllegalArgumentException("Atempted to find the bounds for " + + "a non-rate zero continuous variable that was not found in the " + + "zone."); + } + + // Else find the upper and lower bounds. +// setLowerBoundbydbmIndex(i, range.get_LowerBound()); +// setUpperBoundbydbmIndex(i, range.get_UpperBound()); + setDbmEntry(i, 0, (-1)*range.get_LowerBound()); + setDbmEntry(0, i, range.get_UpperBound()); + + } + + /** + * Converts the index of the DBM to the index of _matrix. + * @param i + * The row/column index of the DBM. + * @return + * The row/column index of _matrix. + */ + private static int dbmIndexToMatrixIndex(int i) + { + return i+1; + } + + /** + * Retrieves an entry of the DBM using the DBM's addressing. + * @param i + * The row of the DBM. + * @param j + * The column of the DBM. + * @return + * The value of the (i, j) element of the DBM. + */ + @Override + public int getDbmEntry(int i, int j) + { + return _matrix[dbmIndexToMatrixIndex(i)][dbmIndexToMatrixIndex(j)]; + } + + /** + * Retrieves an entry of the DBM using LPNTransitionPair indecies. + * @param iPair + * The LPNTransitionPair for the ith entry. + * @param jPair + * The LPNTransitionPair for the jth entry. + * @return + * The value of the (i,j) element of the DBM where i corresponds to the row + * for the variable iPair and j corresponds to the row for the variable jPair. + */ + @Override + public int getDbmEntryByPair(LPNTransitionPair iPair, LPNTransitionPair jPair){ + int iIndex = Arrays.binarySearch(_indexToTimerPair, iPair); + int jIndex = Arrays.binarySearch(_indexToTimerPair, jPair); + return getDbmEntry(iIndex, jIndex); + } + + /** + * Sets an entry of the DBM using the DBM's addressing. + * @param i + * The row of the DBM. + * @param j + * The column of the DBM. + * @param value + * The new value for the entry. + */ + private void setDbmEntry(int i, int j, int value) + { + _matrix[dbmIndexToMatrixIndex(i)][dbmIndexToMatrixIndex(j)] = value; + } + + /** + * Sets the entry in the DBM using the LPNTransitionPair indexing. + * @param row + * The LPNTransitionPair for the row. + * @param col + * The LPNTransitionPair for the column. + * @param value + * The value to set the entry to. + */ + private void setDbmEntryByPair(LPNTransitionPair row, LPNTransitionPair col, int value){ + + // The row index. + int i = timerIndexToDBMIndex(row); + + // The column index. + int j = timerIndexToDBMIndex(col); + + setDbmEntry(i, j, value); + } + + /** + * Returns the index of the the transition in the DBM given a LPNTransitionPair pairing + * the transition index and associated LPN index. + * @param ltPair + * The pairing comprising the index of the transition and the index of the associated + * LPN. + * @return + * The row/column of the DBM associated with the ltPair. + */ + @Override + public int timerIndexToDBMIndex(LPNTransitionPair ltPair) + { + return Arrays.binarySearch(_indexToTimerPair, ltPair); + } + + + /** + * The matrix labeled with 'ti' where i is the transition index associated with the timer. + */ + @Override + public String toString() + { + // TODO : Fix the handling of continuous variables in the + // _lpnList == 0 case. + + String result = "Timer and delay or continuous and ranges.\n"; + + int count = 0; + + // Print the timers. + for(int i=1; i<_indexToTimerPair.length; i++, count++) + { + if(_lpnList.length == 0) + { + // If no LPN's are associated with this Zone, use the index of the timer. + result += " t" + _indexToTimerPair[i].get_transitionIndex() + " : "; + } + else + { + String name; + + // If the current LPNTransitionPair is a timer, get the name + // from the transitions. +// if(_indexToTimerPair[i].get_isTimer()){ + // If the current timer is an LPNTransitionPair and not an LPNContinuousPair + if(!(_indexToTimerPair[i] instanceof LPNContinuousPair)){ + + // Get the name of the transition. + Transition tran = _lpnList[_indexToTimerPair[i].get_lpnIndex()]. + getTransition(_indexToTimerPair[i].get_transitionIndex()); + + name = tran.getLabel(); + } + else{ + // If the current LPNTransitionPair is not a timer, get the + // name as a continuous variable. + Variable var = _lpnList[_indexToTimerPair[i].get_lpnIndex()] + .getContVar(_indexToTimerPair[i].get_transitionIndex()); + + LPNContinuousPair lcPair = + (LPNContinuousPair) _indexToTimerPair[i]; + + int lowerBound = -1*getDbmEntry(i, 0)*lcPair.getCurrentRate(); + int upperBound = getDbmEntry(0, i)*lcPair.getCurrentRate(); + + // If the rate is negative, the bounds are switched + // in the zone. + if(lcPair.getCurrentRate() < 0){ + int tmp = lowerBound; + lowerBound = upperBound; + upperBound = tmp; + } + + name = var.getName() + + ":[" + lowerBound + "," + upperBound + "]\n" + + " Current Rate: " + lcPair.getCurrentRate() + " " + + "rate:"; + } + +// result += " " + tran.getName() + ":"; + + result += " " + name + ":"; + } + result += "[ " + -1*getLowerBoundbydbmIndex(i) + ", " + getUpperBoundbydbmIndex(i) + " ]"; + + if(count > 9) + { + result += "\n"; + count = 0; + } + } + + if(!_rateZeroContinuous.isEmpty()){ + result += "\nRate Zero Continuous : \n"; + for (LPNContAndRate lcrPair : _rateZeroContinuous.keySet()){ + result += "" + _rateZeroContinuous.get(lcrPair) + + "Rate: " + lcrPair.get_rateInterval(); + } + } + + result += "\nDBM\n"; + + + // Print the DBM. + for(int i=0; i<_indexToTimerPair.length; i++) + { + result += "| " + String.format("%3d", getDbmEntry(i, 0)); + + for(int j=1; j<_indexToTimerPair.length; j++) + { + + result += ", " + String.format("%3d",getDbmEntry(i, j)); + } + + result += " |\n"; + } + + + return result; + } + + /** + * Tests for equality. Overrides inherited equals method. + * @return True if o is equal to this object, false otherwise. + */ + @Override + public boolean equals(Object o) + { + // Check if the reference is null. + if(o == null) + { + return false; + } + + // Check that the type is correct. + if(!(o instanceof Zone)) + { + return false; + } + + // Check for equality using the Zone equality. + return equals((Zone) o); + } + + + /** + * Tests for equality. + * @param + * The Zone to compare. + * @return + * True if the zones are non-null and equal, false otherwise. + */ + public boolean equals(Zone otherZone) + { + // Check if the reference is null first. + if(otherZone == null) + { + return false; + } + + // Check for reference equality. + if(this == otherZone) + { + return true; + } + + // If the hash codes are different, then the objects are not equal. + if(this.hashCode() != otherZone.hashCode()) + { + return false; + } + + // Check if the they have the same number of timers. + if(this._indexToTimerPair.length != otherZone._indexToTimerPair.length){ + return false; + } + + // Check if the timers are the same. + for(int i=0; i getDbmEntry(i, k) + getDbmEntry(k, j)) + { + setDbmEntry(i, j, getDbmEntry(i, k) + getDbmEntry(k, j)); + } + + if( (i==j) && getDbmEntry(i, j) != 0) + { + throw new DiagonalNonZeroException("Entry (" + i + ", " + j + ")" + + " became " + getDbmEntry(i, j) + "."); + } + } + } + } + } + + /** + * Determines if a timer associated with a given transitions has reached its lower bound. + * @param t + * The transition to consider. + * @return + * True if the timer has reached its lower bound, false otherwise. + */ + public boolean exceedsLowerBoundbyTransitionIndex(Transition t) + { + LPN lpn = t.getLpn(); + + int lpnIndex = lpn.getLpnIndex(); + + int transitionIndex = t.getIndex(); + +// LPNTransitionPair ltPair = new LPNTransitionPair(lpnIndex, transitionIndex, true); + LPNTransitionPair ltPair = new LPNTransitionPair(lpnIndex, transitionIndex); + + return exceedsLowerBoundbydbmIndex(Arrays.binarySearch(_indexToTimerPair, ltPair)); + } + + /** + * Determines if a timer has reached its lower bound. + * @param timer + * The timer's index. + * @return + * True if the timer has reached its lower bound, false otherwise. + */ + public boolean exceedsLowerBoundbydbmIndex(int index) + { + + // Note : Make sure that the lower bound is stored as a negative number + // and that the inequality is correct. + return _matrix[0][dbmIndexToMatrixIndex(index)] <= + _matrix[1][dbmIndexToMatrixIndex(index)]; + } + + /* (non-Javadoc) + * @see verification.timed_state_exploration.zone.Zone#fireTransitionbyTransitionIndex(int, int[], verification.platu.stategraph.State) + */ +// public Zone fireTransitionbyTransitionIndex(int timer, int[] enabledTimers, +// State state) +// { +// // TODO: Check if finish. +// int index = Arrays.binarySearch(_indexToTimer, timer); +// +// //return fireTransitionbydbmIndex(Arrays.binarySearch(_indexToTimer, timer), +// //enabledTimers, state); +// +// // Check if the value is in this zone to fire. +// if(index < 0){ +// return this; +// } +// +// return fireTransitionbydbmIndex(index, enabledTimers, state); +// } + + /** + * Gives the Zone obtained by firing a given Transitions. + * @param t + * The transitions being fired. + * @param enabledTran + * The list of currently enabled Transitions. + * @param localStates + * The current local states. + * @return + * The Zone obtained by firing Transition t with enabled Transitions enabled + * enabledTran when the current state is localStates. + */ +// public Zone fire(Transition t, LpnTranList enabledTran, ArrayList> newAssignValues, +// State[] localStates){ +// public Zone fire(Transition t, LpnTranList enabledTran, +// ArrayList newAssignValues, +// State[] localStates){ + @Override + public Zone fire(Transition t, LpnTranList enabledTran, + ContinuousRecordSet newAssignValues, + State[] localStates){ + + + try { + if(_writeLogFile != null){ + _writeLogFile.write(t.toString()); + _writeLogFile.newLine(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + // Create the LPNTransitionPair to check if the Transitions is in the zone and to + // find the index. + LPN lpn = t.getLpn(); + + int lpnIndex = lpn.getLpnIndex(); + + int transitionIndex = t.getIndex(); + + LPNTransitionPair ltPair = new LPNTransitionPair(lpnIndex, transitionIndex); + + int dbmIndex = Arrays.binarySearch(_indexToTimerPair, ltPair); + + if(dbmIndex <= 0){ + return this; + } + + // Get the new zone portion. + Zone newZone = fireTransitionbydbmIndexNew(dbmIndex, enabledTran, localStates, + newAssignValues); + + // Update any assigned continuous variables. + //newZone.updateContinuousAssignment(newAssignValues); + + + // Set all the rates to their lower bound. + newZone.setAllToLowerBoundRate(); + + // Warp the Zone + newZone.dbmWarp(this); + + // Warping can wreck the newly assigned values so correct them. + newZone.correctNewAssignemnts(newAssignValues); + + newZone.recononicalize(); + + newZone.advance(localStates); + + // Recanonicalize + newZone.recononicalize(); + + + newZone.checkZoneMaxSize(); + + + return newZone; + } + + /** + * Updates the Zone according to the transition firing. + * @param index + * The index of the timer. + * @param newContValue + * @return + * The updated Zone. + */ + public Zone fireTransitionbydbmIndex(int index, LpnTranList enabledTimers, + State[] localStates, + ArrayList> newAssignValues) +// { +// public Zone fireTransitionbydbmIndex(int index, LpnTranList enabledTimers, +// State[] localStates, +//// ArrayList newAssignValues) +// public Zone fireTransitionbydbmIndex(int index, LpnTranList enabledTimers, +// State[] localStates, +// ContinuousRecordSet newAssignValues) + { + /* + * For the purpose of adding the newly enabled transitions and removing + * the disable transitions, the continuous variables that still have + * a nonzero rate can be treated like still enbaled timers. + */ + + // Initialize the zone. + Zone newZone = new Zone(); + + // These sets will defferentiate between the new timers and the + // old timers, that is between the timers that are not already in the + // zone and those that are already in the zone.. + HashSet newTimers = new HashSet(); + HashSet oldTimers = new HashSet(); + + // Copy the LPNs over. + newZone._lpnList = new LPN[this._lpnList.length]; + for(int i=0; i oldNonZero = newAssignValues.get(3); + + + + // Add the continuous variables to the enabled timers. + for(int i=1; _indexToTimerPair[i] instanceof LPNContinuousPair; i++){ + // For the purpose of addigng continuous variables to the zone + // consider an oldNonZero continuous variable as new. + if(oldNonZero.containsKey(_indexToTimerPair[i])){ + continue; + } + oldTimers.add(_indexToTimerPair[i]); + } + + + for(int i=0; i= 0 ) + { + // The timer was already present in the zone. + oldTimers.add(newZone._indexToTimerPair[i]); + } + else + { + // The timer is a new timer. + newTimers.add(newZone._indexToTimerPair[i]); + } + } + + // Create the new matrix. + newZone._matrix = new int[newZone.matrixSize()][newZone.matrixSize()]; + + // TODO: For simplicity, make a copy of the current zone and perform the + // restriction and re-canonicalization. Later add a copy re-canonicalization + // that does the steps together. + + Zone tempZone = this.clone(); + + tempZone.restrictTimer(index); + tempZone.recononicalize(); + + // Copy the tempZone to the new zone. + for(int i=0; i varValues = + _lpnList[pair.get_lpnIndex()] + .getAllVarsWithValuesAsString(localStates[pair.get_lpnIndex()].getVariableVector()); + + // Set the upper and lower bound. + int upper, lower; + if(delay.getOp().equals("uniform")) + { + + IntervalPair lowerRange = delay.getLeftChild() + .evaluateExprBound(varValues, null, null); + IntervalPair upperRange = delay.getRightChild() + .evaluateExprBound(varValues, null, null); + + // The lower and upper bounds should evaluate to a single + // value. Yell if they don't. + if(!lowerRange.singleValue() || !upperRange.singleValue()){ + throw new IllegalStateException("When evaulating the delay, " + + "the lower or the upper bound evaluated to a range " + + "instead of a single value."); + } + + lower = lowerRange.get_LowerBound(); + upper = upperRange.get_UpperBound(); + + } + else + { + + IntervalPair range = delay.evaluateExprBound(varValues, this, null); + + lower = range.get_LowerBound(); + upper = range.get_UpperBound(); + } + + newZone.setLowerBoundByLPNTransitionPair(pair, lower); + newZone.setUpperBoundByLPNTransitionPair(pair, upper); + + } + + //newZone.advance(); + // Advance time. +// newZone.advance(localStates); + + // Recanonicalize. +// newZone.recononicalize(); +// +// newZone.checkZoneMaxSize(); + + return newZone; + } + + + + + public Zone fireTransitionbydbmIndexNew(int index, LpnTranList enabledTimers, + State[] localStates, + ContinuousRecordSet newAssignValues) + { + /* + * For the purpose of adding the newly enabled transitions and removing + * the disable transitions, the continuous variables that still have + * a nonzero rate can be treated like still enbaled timers. + */ + + // Initialize the zone. + Zone newZone = new Zone(); + + // These sets will defferentiate between the new timers and the + // old timers, that is between the timers that are not already in the + // zone and those that are already in the zone.. + HashSet newTimers = new HashSet(); + HashSet oldTimers = new HashSet(); + + // Copy the LPNs over. + newZone._lpnList = new LPN[this._lpnList.length]; + for(int i=0; i oldNonZero = newAssignValues.get(3); + + + + // Add the continuous variables to the enabled timers. +// for(int i=1; _indexToTimerPair[i] instanceof LPNContinuousPair; i++){ +// // For the purpose of addigng continuous variables to the zone +// // consider an oldNonZero continuous variable as new. +// if(oldNonZero.containsKey(_indexToTimerPair[i])){ +// continue; +// } +// oldTimers.add(_indexToTimerPair[i]); +// } + + + for(int i=0; i= 0 ) + { + // The timer was already present in the zone. + oldTimers.add(newZone._indexToTimerPair[i]); + } + else + { + // The timer is a new timer. + newTimers.add(newZone._indexToTimerPair[i]); + } + } + + // Create the new matrix. + newZone._matrix = new int[newZone.matrixSize()][newZone.matrixSize()]; + + // TODO: For simplicity, make a copy of the current zone and perform the + // restriction and re-canonicalization. Later add a copy re-canonicalization + // that does the steps together. + + Zone tempZone = this.clone(); + + tempZone.restrictTimer(index); + tempZone.recononicalize(); + + // Copy the tempZone to the new zone. + for(int i=0; i= 0){ + +// // Copy the smallest and greatest continuous value. +// newZone.setDbmEntryByPair(LPNTransitionPair.ZERO_TIMER_PAIR, +// lcPair, -1*values.get_LowerBound()); +// +// newZone.setDbmEntryByPair(lcPair, +// LPNTransitionPair.ZERO_TIMER_PAIR, +// values.get_UpperBound()); + + // Copy the smallest and greatest continuous value. + newZone.setDbmEntryByPair(lcPair, + LPNTransitionPair.ZERO_TIMER_PAIR, + ContinuousUtilities.chkDiv(-1*values.get_LowerBound(), + currentRate, true)); + + newZone.setDbmEntryByPair(LPNTransitionPair.ZERO_TIMER_PAIR, + lcPair, + ContinuousUtilities.chkDiv(values.get_UpperBound(), + currentRate, true)); + } + else{ + // Copy the smallest and greatest continuous value. + // For negative rates, the upper and lower bounds need + // to be switched. + newZone.setDbmEntryByPair(LPNTransitionPair.ZERO_TIMER_PAIR, + lcPair, + ContinuousUtilities.chkDiv(values.get_LowerBound(), + currentRate, true)); + + newZone.setDbmEntryByPair(lcPair, + LPNTransitionPair.ZERO_TIMER_PAIR, + ContinuousUtilities.chkDiv(-1*values.get_UpperBound(), + currentRate, true)); + } + + continue; + } + + + // Get all the upper and lower bounds for the new timers. + // Get the name for the timer in the i-th column/row of DBM + String tranName = _lpnList[pair.get_lpnIndex()] + .getTransition(pair.get_transitionIndex()).getLabel(); + ExprTree delay = _lpnList[pair.get_lpnIndex()].getDelayTree(tranName); + + if(delay == null){ + _lpnList[pair.get_lpnIndex()].changeDelay(tranName, "0"); + delay = _lpnList[pair.get_lpnIndex()].getDelayTree(tranName); + } + + // Get the values of the variables for evaluating the ExprTree. + HashMap varValues = + _lpnList[pair.get_lpnIndex()] + .getAllVarsWithValuesAsString(localStates[pair.get_lpnIndex()] + .getVariableVector()); + + // Set the upper and lower bound. + int upper, lower; + if(delay.getOp().equals("uniform")) + { + + IntervalPair lowerRange = delay.getLeftChild() + .evaluateExprBound(varValues, null, null); + IntervalPair upperRange = delay.getRightChild() + .evaluateExprBound(varValues, null, null); + + // The lower and upper bounds should evaluate to a single + // value. Yell if they don't. + if(!lowerRange.singleValue() || !upperRange.singleValue()){ + throw new IllegalStateException("When evaulating the delay, " + + "the lower or the upper bound evaluated to a range " + + "instead of a single value."); + } + + lower = lowerRange.get_LowerBound(); + upper = upperRange.get_UpperBound(); + + } + else + { + + IntervalPair range = delay.evaluateExprBound(varValues, this, null); + + lower = range.get_LowerBound(); + upper = range.get_UpperBound(); + } + + newZone.setLowerBoundByLPNTransitionPair(pair, lower); + newZone.setUpperBoundByLPNTransitionPair(pair, upper); + + } + + + //Erase relationships for continuous variables that have had new values + // assigned to them or a new non-rate zero value. + for(int i = 1; i0){ + setDbmEntry(i, 0, + ContinuousUtilities.chkDiv(-1*values.get_LowerBound(), + currentRate, true)); + setDbmEntry(0,i, + ContinuousUtilities.chkDiv(values.get_UpperBound(), + currentRate, true)); + } + else{ + setDbmEntry(i,0, + ContinuousUtilities.chkDiv(-1*values.get_UpperBound(), + currentRate, true)); + + setDbmEntry(0, i, + ContinuousUtilities.chkDiv(values.get_LowerBound(), + currentRate, true)); + } + + // Erase the relationships. + for(int j=1; j newZeroContValues, +// HashMap newNonZeroContValues){ + +// newZone._rateZeroContinuous = new DualHashMap(); +// +// +// +// // Copy the zero rate variables over if they are still rate zero. +// for(Entry entry : _rateZeroContinuous.entrySet()){ +// LPNContinuousPair thePair = (LPNContinuousPair) entry.getKey(); +// VariableRangePair rangeValue = entry.getValue(); +// +// // Check if the pairing is in the newNonZeroContValues. +// IntervalPair interval = newNonZeroContValues.get(thePair); +// if(interval == null){ +// // Interval being null indicates that the key was not +// // found. +// newZone._rateZeroContinuous.put(thePair, rangeValue); +// } +// } +// } + + /** + * Handles the moving of the continuous variables in and out of the + * _rateZeroContinuous. This includes the adding of all rate zero (new and old) + * cotninuous variables to the _rateZeroContinuous, and creating the + * _indexToTimerPair and populating it. + * @param newZone The Zone being constructed. + * @param enabled The list of enabled transitions. + * The enabled transitions. + * @param newAssignValues The list of continuous variable update information. + */ +// private void copyRates(Zone newZone, LpnTranList enabledTran, +// ArrayList> newAssignValues){ +// private void copyRates(Zone newZone, LpnTranList enabledTran, +// ArrayList newAssignValues){ + @SuppressWarnings("unused") + private void copyRates(Zone newZone, LpnTranList enabledTran, + ContinuousRecordSet newAssignValues){ + /* + * The newAssignValues is an ArrayList of four sets. + * 0. Rate zero gets zero assigned. + * 1. Rate zero gets non-zero rate assigned. + * 2. Non-zero gets zero rate assigned. + * 3. Non-zero gets non-zero rate assigned. + */ + +// final int OLD_ZERO = 0; // Case 0 in description. +// final int NEW_NON_ZERO = 1; // Case 1 in description. +// final int NEW_ZERO = 2; // Case 2 in description. +// final int OLD_NON_ZERO = 3; // Case 3 in description. Isn't used. + + +// HashMap oldRateZero = +// newAssignValues.get(OLD_ZERO); +// +// HashMap newNonZeroRate = +// newAssignValues.get(NEW_NON_ZERO); +// +// HashMap newRateZero = +// newAssignValues.get(NEW_ZERO); +// HashMap oldNonZero = +// newAssignValues.get(OLD_NON_ZERO); + + // Create new rate zero member variable. + newZone._rateZeroContinuous = new DualHashMap(); + + // Create new _indexToTimerPair. + // First get the total number of non-zero rate continuous variables that + // are present in the old zone. + int totalContinuous = 0; + for(int i=0; i<_lpnList.length; i++){ + totalContinuous += _lpnList[i].getTotalNumberOfContVars(); + } + + int numberNonZero = totalContinuous - _rateZeroContinuous.size(); + + // The size is given by + // total number of transitions + // + number of non-zero rate continuous variables previously in the zone + // + number of zero rate continuous variables that now have non-zero + // - number of non-zero rate continuous variables that are now zero + // + 1 for the zero timer. +// +// int newSize = enabledTran.size() +// + numberNonZero + newAssignValues.get(NEW_NON_ZERO).size() +// - newAssignValues.get(NEW_ZERO).size() + 1; + + // TODO: Create an object that stores the records along with this information. + int newNonZero = 0, newZero = 0; + for(UpdateContinuous record : newAssignValues.keySet()){ + if(record.newlyNonZero()){ + newNonZero++; + } + if(record.newlyZero()){ + newZero++; + } + } + + int newSize = enabledTran.size() + numberNonZero + newNonZero - newZero + 1; + + + // Create the timer array. + newZone._indexToTimerPair = new LPNTransitionPair[newSize]; + + // Add in the zero timer. + newZone._indexToTimerPair[0] = LPNTransitionPair.ZERO_TIMER_PAIR; + + // Copy over the rate zero conintinuous variables. + // First copy over all the continuous variables that still have + // rate zero. +// for(LPNTransitionPair ltTranPair : _rateZeroContinuous.keySet()){ +// // Cast the index. +// LPNContinuousPair ltContPair = (LPNContinuousPair) ltTranPair; +// if(newNonZeroRate.containsKey(ltContPair)){ +// // The variable no longer is rate zero, so do nothing. +// continue; +// } +// +// // If the value has had an assignment, use the new values instead. +// if(oldRateZero.containsKey(new LPNContAndRate(ltContPair))){ +// // Create the new VariableRangePair to add. +// Variable v = _lpnList[ltContPair.get_lpnIndex()] +// .getContVar(ltContPair.get_ContinuousIndex()); +// VariableRangePair vrp = +// new VariableRangePair(v, oldRateZero.get(new LPNContAndRate(ltContPair))); +// +// newZone._rateZeroContinuous.put(ltContPair, vrp); +// } +// else{ +// newZone._rateZeroContinuous.put(ltTranPair, _rateZeroContinuous.get(ltTranPair)); +// } +// +// } + + // Copy over the rate zero continuous variables. + // First copy over all the continuous variables that still have + // rate zero. + for(LPNContAndRate ltTranPair : _rateZeroContinuous.keySet()){ + // Cast the index. + LPNContinuousPair ltContPair = ltTranPair.get_lcPair(); + if(!newAssignValues.get(ltContPair).is_newZero()){ + // The variable no longer is rate zero, so do nothing. + continue; + } + + // If the value has had an assignment, use the new values instead. +// if(oldRateZero.containsKey(new LPNContAndRate(ltContPair))){ + if(newAssignValues.contains(ltContPair)){ + // Create the new VariableRangePair to add. + Variable v = _lpnList[ltContPair.get_lpnIndex()] + .getContVar(ltContPair.get_ContinuousIndex()); +// VariableRangePair vrp = +// new VariableRangePair(v, +// oldRateZero.get(new LPNContAndRate(ltContPair))); + VariableRangePair vrp = + new VariableRangePair(v, + newAssignValues.get(ltContPair).get_Value()); + + newZone._rateZeroContinuous.insert( + new LPNContAndRate(ltContPair, new IntervalPair(0,0)), vrp); + } + else{ + newZone._rateZeroContinuous + .insert(ltTranPair, _rateZeroContinuous.get(ltTranPair)); + } + + } + + // Next add the values that are newly set to rate zero. +// for(LPNContAndRate ltCar : newRateZero.keySet()){ +// // Exract the variable. +// Variable v = _lpnList[ltCar.get_lcPair().get_lpnIndex()]. +// getContVar(ltCar.get_lcPair().get_ContinuousIndex()); +// +// // Create a VariableRangePair. +// VariableRangePair vrp = new VariableRangePair(v, newRateZero.get(ltCar.get_lcPair())); +// +// // Add the value to the map. +// newZone._rateZeroContinuous.put(ltCar.get_lcPair(), vrp); +// } + +// for(LPNContAndRate ltCar : newRateZero.keySet()){ +// // Exract the variable. +// Variable v = _lpnList[ltCar.get_lcPair().get_lpnIndex()]. +// getContVar(ltCar.get_lcPair().get_ContinuousIndex()); +// +// // Create a VariableRangePair. +// VariableRangePair vrp = new VariableRangePair(v, newRateZero.get(ltCar.get_lcPair())); +// +// // Add the value to the map. +// newZone._rateZeroContinuous.put(ltCar.get_lcPair(), vrp); +// } + + // We still need to add in the rate zero continuous variables whose rate remains zero + // since their range might have changed. We could check if the range has changed, but + // its just as easy (or easier) to simply add it anyway. + + // Added the indecies for the non-zero rate continuous variables to the + // _indexToTimer array. + // Start with the values already in the old array. +// int index = 1; // Index for the next continuous index object. +// for(int i=1; this._indexToTimerPair[i] instanceof LPNContinuousPair; i++){ +// // Check that the value should not be removed. +// LPNContAndRate lcar = new LPNContAndRate((LPNContinuousPair) _indexToTimerPair[i]); +// +// if(newRateZero.containsKey(lcar)){ +// continue; +// } +//// else if (oldNonZero.containsKey(lcar)){ +//// continue; +//// } +// else if (oldRateZero.containsKey(lcar)){ +// continue; +// } +// else{ +// newZone._indexToTimerPair[index++] = this._indexToTimerPair[i].clone(); +// } +// } + + // Change to the new references for the oldNonZero. This change to the + // new current rate. +// for(LPNContAndRate lcar : oldNonZero.keySet()){ +// int oldIndex = Arrays.binarySearch(_indexToTimerPair, lcar.get_lcPair()); +// _indexToTimerPair[oldIndex] = lcar.get_lcPair(); +// } + + // Add in the indecies for the new non-zero into the old array. +// for(LPNContinuousPair ltCont : newNonZeroRate.keySet()){ +// for(LPNContAndRate ltCar : newNonZeroRate.keySet()){ +//// newZone._indexToTimerPair[index++] = ltCont; +// newZone._indexToTimerPair[index++] = ltCar.get_lcPair(); +// } + +// Arrays.sort(newZone._indexToTimerPair); + + // Copy over the new transitions. +// for(Transition t : enabledTran){ +//// newZone._indexToTimerPair[index++] = ; +// int lpnIndex = t.getLpn().getLpnIndex(); +// int tranIndex = t.getIndex(); +// newZone._indexToTimerPair[index++] = +// new LPNTransitionPair (lpnIndex, tranIndex); +// } + + Arrays.sort(newZone._indexToTimerPair); + + } + + + private void copyRatesNew(Zone newZone, LpnTranList enabledTran, + ContinuousRecordSet newAssignValues){ + + // Create new rate zero member variable. + newZone._rateZeroContinuous = new DualHashMap(); + + // Create new _indexToTimerPair. + // First get the total number of non-zero rate continuous variables that + // are present in the old zone. + int totalContinuous = 0; + for(int i=0; i<_lpnList.length; i++){ + totalContinuous += _lpnList[i].getTotalNumberOfContVars(); + } + + int numberNonZero = totalContinuous - _rateZeroContinuous.size(); + + // The size is given by + // total number of transitions + // + number of non-zero rate continuous variables previously in the zone + // + number of zero rate continuous variables that now have non-zero + // - number of non-zero rate continuous variables that are now zero + // + 1 for the zero timer. + // + // int newSize = enabledTran.size() + // + numberNonZero + newAssignValues.get(NEW_NON_ZERO).size() + // - newAssignValues.get(NEW_ZERO).size() + 1; + + // TODO: Create an object that stores the records along with this information. + int newNonZero = 0, newZero = 0; + for(UpdateContinuous record : newAssignValues.keySet()){ + if(record.newlyNonZero()){ + newNonZero++; + } + if(record.newlyZero()){ + newZero++; + } + } + + int newSize = enabledTran.size() + numberNonZero + newNonZero - newZero + 1; + + + // Create the timer array. + newZone._indexToTimerPair = new LPNTransitionPair[newSize]; + + // Add in the zero timer. + newZone._indexToTimerPair[0] = LPNTransitionPair.ZERO_TIMER_PAIR; + + int indexTimerCount = 1; + + + // Sort the previous rate zero continuous variables into rate zero or non-zero. + for(LPNContAndRate ltTranPair : _rateZeroContinuous.keySet()){ + // Cast the index. + LPNContinuousPair ltContPair = ltTranPair.get_lcPair(); + + // Check if the variable is a newly assigned value. + UpdateContinuous assignedLtContPair = newAssignValues.get(ltContPair); + + if(assignedLtContPair != null){ + + if(assignedLtContPair.newlyNonZero()){ + // Variable was zero and is now non-zero, so add to the the non-zero + // references. + newZone._indexToTimerPair[indexTimerCount++] = + assignedLtContPair.get_lcrPair().get_lcPair().clone(); + } + else{ + // Variable was zero and is still zero, but an assignment has been + // made. Simply add in the new assigned value. + VariableRangePair vrp = this._rateZeroContinuous.get(ltTranPair); + + newZone._rateZeroContinuous.insert(assignedLtContPair.get_lcrPair(), + new VariableRangePair(vrp.get_variable(), + assignedLtContPair.get_Value())); + + } + } + else{ + newZone._rateZeroContinuous + .insert(ltTranPair, _rateZeroContinuous.get(ltTranPair)); + } + } + + + // Sort the previous non-zero variables into the rate zero and non-zero. + for(int i=1; this._indexToTimerPair[i] instanceof LPNContinuousPair; i++){ + + LPNContinuousPair lcPair = (LPNContinuousPair) this._indexToTimerPair[i]; + + // Check if an assignment has been made. + UpdateContinuous updateRecord = newAssignValues.get(lcPair); + + if(updateRecord != null){ + + if(updateRecord.is_newZero()){ + // The continuous variable is now a rate zero variable. + + LPNContinuousPair ltCar = updateRecord.get_lcrPair().get_lcPair(); + + Variable v = _lpnList[ltCar.get_lpnIndex()]. + getContVar(ltCar.get_ContinuousIndex()); + + // Dewarp the upper and lower bounds. + IntervalPair values = updateRecord.get_Value(); + int currentRate = getCurrentRate(ltCar); + values.set_LowerBound( + values.get_LowerBound() * currentRate); + values.set_UpperBound( + values.get_UpperBound() * currentRate); + + // Create a VariableRangePair. + VariableRangePair vrp = new VariableRangePair(v, + values); + + // Add the value to the map. +// newZone._rateZeroContinuous.put(ltCar, vrp); + newZone._rateZeroContinuous.insert(updateRecord.get_lcrPair(), vrp); + } + else{ + // This non-zero variable still has rate non-zero, but replace + // with the newAssignValues since the rate may have changed. + newZone._indexToTimerPair[indexTimerCount++] = + updateRecord.get_lcrPair().get_lcPair(); + } + + } + else{ + // The variable was non-zero and hasn't had an assignment. + newZone._indexToTimerPair[indexTimerCount++] = + this._indexToTimerPair[i].clone(); + } + + } + + + // Copy over the new transitions. + for(Transition t : enabledTran){ + int lpnIndex = t.getLpn().getLpnIndex(); + int tranIndex = t.getIndex(); + newZone._indexToTimerPair[indexTimerCount++] = + new LPNTransitionPair (lpnIndex, tranIndex); + } + + Arrays.sort(newZone._indexToTimerPair); + + } + + /** + * Advances time. + */ + private void advance() + { + for(int i=0; i newTimers, + Collection oldTimers, State[] localStates){ + + + // Copy the tempZone to the new zone. + for(int i=0; i varValues = + _lpnList[pair.get_lpnIndex()] + .getAllVarsWithValuesAsString(localStates[pair.get_lpnIndex()].getVariableVector()); + + // Set the upper and lower bound. + int upper, lower; + if(delay.getOp().equals("uniform")) + { + IntervalPair lowerRange = delay.getLeftChild() + .evaluateExprBound(varValues, null, null); + IntervalPair upperRange = delay.getRightChild() + .evaluateExprBound(varValues, null, null); + + // The lower and upper bounds should evaluate to a single + // value. Yell if they don't. + if(!lowerRange.singleValue() || !upperRange.singleValue()){ + throw new IllegalStateException("When evaulating the delay, " + + "the lower or the upper bound evaluated to a range " + + "instead of a single value."); + } + + lower = lowerRange.get_LowerBound(); + upper = upperRange.get_UpperBound(); + + } + else + { + IntervalPair range = delay.evaluateExprBound(varValues, this, null); + + lower = range.get_LowerBound(); + upper = range.get_UpperBound(); + } + + setLowerBoundByLPNTransitionPair(pair, lower); + setUpperBoundByLPNTransitionPair(pair, upper); + + } + } + + /** + * This method sets all the rate to their lower bound. + * Will not work quite right for continuous variables + * with rates that include zero. + */ + private void setAllToLowerBoundRate(){ + + // Loop through the continuous variables. + for(int i=1; i<_indexToTimerPair.length && + _indexToTimerPair[i] instanceof LPNContinuousPair; i++){ + LPNContinuousPair ltContPair = (LPNContinuousPair) _indexToTimerPair[i]; + + // For this, recall that for a continuous variable that the lower bound + // rate is stored in the zero column of the matrix. +// setCurrentRate(ltContPair, +// -1*getDbmEntry(0, +// dbmIndexToMatrixIndex(i))); + + int lower = -1*_matrix[dbmIndexToMatrixIndex(i)][0]; + int upper = _matrix[0][dbmIndexToMatrixIndex(i)]; + int newRate; + +// if(upper == 0){ +// newRate = lower; +// } +// +// else if(lower == 0 || lower < 0 & upper > 0){ +// newRate = upper; +// } +// +// else{ +// newRate = Math.abs(lower) < Math.abs(upper) ? lower : upper; +// } + + /** + * Suppose the range of rates is [a,b]. If a>=0, then we set the + * rate to b. If b<=0, then we set the rate to a. Ohterwise, + * a<0=0 or lower < 0 < upper we set the + // rate to the upper bound. + newRate = upper; + } + +// setCurrentRate(ltContPair, +// -1*_matrix[dbmIndexToMatrixIndex(i)][0]); + setCurrentRate(ltContPair, newRate); + } + } + + /** + * Resets the rates of all continuous variables to be their + * lower bounds. + */ + @Override + public Zone resetRates(){ + + // Create the new zone. +// Zone newZone = new Zone(); +// +// // Copy the rate zero variables. +// newZone._rateZeroContinuous = this._rateZeroContinuous.clone(); +// +// +// // Copy the LPNs over. +// newZone._lpnList = new LhpnFile[this._lpnList.length]; +// for(int i=0; i= 0){ +// // The rate zero is in the range, so this will be +// // the new current rate. +// +// rateZero[i] = true; +// +// LPNContinuousPair lcPair = +// (LPNContinuousPair) this._indexToTimerPair[i].clone(); +// +// lcPair.setCurrentRate(0); +// +// // Save as a rate zero continuous variable. +// LPNContAndRate newRateZero = +// new LPNContAndRate(lcPair, +// this.getRateBounds(lcPair)); +// +// VariableRangePair vcp = +// new VariableRangePair( +// this._lpnList[lcPair.get_lpnIndex()] +// .getContVar(lcPair.get_ContinuousIndex()), +// this.getContinuousBounds(lcPair)); +// +// newZone._rateZeroContinuous.insert(newRateZero, vcp); +// +// // Update continuous variable counter. +// zeroCount++; +// } +// } +// +// +// // Save over the indexToTimer pairs. +// newZone._indexToTimerPair = +// new LPNTransitionPair[this._indexToTimerPair.length-zeroCount]; +// +// +// for(int i=0, j=0; i=1 && rateZero[i-1]){ +// ioffset++; +// } +// +// for(int j=0, joffset=0; j=1 && rateZero[j-1]){ +// joffset++; +// } +// +// newZone._matrix[i][j] = this._matrix[i+ioffset][j+joffset]; +// } +// } + + + // Warp +// newZone.dbmWarp(this); +// +// newZone.recononicalize(); +// +// return newZone; + + /* + * Create a new zone. + */ + + Zone newZone = new Zone(); + + // Copy the LPNs over. + newZone._lpnList = new LPN[this._lpnList.length]; + for(int i=0; i(); + + HashSet> newlyNonZero = + new HashSet>(); + + for(Map.Entry variable : + _rateZeroContinuous.entrySet()){ + + // Check for a single value which indicates that zero is + // the only possible rate. +// if(variable.getValue().get_range().singleValue()){ + if(variable.getKey().get_rateInterval().singleValue()){ + // This variable only has zero as a rate so keep it + // in the rate zero variables. + newZone._rateZeroContinuous.insert(variable.getKey(), + variable.getValue()); + } + else{ + // This variable will need to be added to the zone. + newlyNonZero.add(variable); + } + } + + + /* + * Calulate the size of the _indexToTimerPairs array and create + * it. + */ + + int oldSize = this._indexToTimerPair.length; + int newSize = oldSize + newlyNonZero.size(); + + newZone._indexToTimerPair = new LPNTransitionPair[newSize]; + + /* + * Copy over the old pairs and add the new ones. + */ + for(int i=0; i< this._indexToTimerPair.length; i++){ + newZone._indexToTimerPair[i] = this._indexToTimerPair[i].clone(); + } + + for(Map.Entry variable : + newlyNonZero){ + newZone._indexToTimerPair[oldSize++] = variable.getKey() + .get_lcPair().clone(); + } + + + /* + * Sort. + */ + Arrays.sort(newZone._indexToTimerPair); + + + /* + * Copy over the old matrix values and new constraints. + */ + newZone._matrix = new int[newZone.matrixSize()][newZone.matrixSize()]; + + for(int i =0; i< this.dbmSize(); i++){ + + int newi = Arrays.binarySearch(newZone._indexToTimerPair, + this._indexToTimerPair[i]); + + if(newi < 0){ + System.err.println("In resetRates, old value was not found"+ + " in new value."); + continue; + } + + // Copy upper and lower bounds for the variable. + newZone._matrix[dbmIndexToMatrixIndex(newi)][0] = + this._matrix[dbmIndexToMatrixIndex(i)][0]; + newZone._matrix[0][dbmIndexToMatrixIndex(newi)] = + this._matrix[0][dbmIndexToMatrixIndex(i)]; + + + // Copy the DBM Entry + for(int j=0; j< this.dbmSize(); j++){ + int newj = Arrays.binarySearch(newZone._indexToTimerPair, + this._indexToTimerPair[j]); + + if(newj < 0){ + System.err.println("In resetRates, old value was not"+ + " found in new value."); + continue; + } + + newZone.setDbmEntry(newi, newj, this.getDbmEntry(i, j)); + } + } + + for(Map.Entry variable: newlyNonZero){ + LPNTransitionPair currentVariable = variable.getKey().get_lcPair(); + + int currentIndex = Arrays.binarySearch(newZone._indexToTimerPair, + currentVariable); + + IntervalPair rangeOfRates = variable.getKey().get_rateInterval(); + IntervalPair rangeOfValues = variable.getValue().get_range(); + + /* + * First set the range of rates, current rate, and the lower and upper + * bounds for the newly added continuous variables. + */ + newZone.setLowerBoundbydbmIndex(currentIndex, rangeOfRates.get_LowerBound()); + newZone.setUpperBoundbydbmIndex(currentIndex, rangeOfRates.get_UpperBound()); + newZone.setDbmEntry(currentIndex, 0, -1*rangeOfValues.get_LowerBound()); + newZone.setDbmEntry(0, currentIndex, rangeOfValues.get_UpperBound()); + + for(int j=1; jz,-2,p); +////for(unsigned i=0;itype > 4) { +//// continue; +//// } +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("Zone to check...\n"); +//// printZ(s->z,events,nevents,s->r); +//// printf("Checking ..."); +//// printI(ineqL[i],events); +//// printf("\n"); +////#endif +//// if(ineqL[i]->place == p) { +// +// // Get all the inequalities that reference the variable of interest. +// ArrayList inequalities = variable.getInequalities(); +// +// for(InequalityVariable ineq : inequalities){ +// +//// ineq_update(ineqL[i],s,nevents); +// +// // Update the inequality variable. +// int ineqValue = ineq.evaluate(localStates[varIndex], this); +// +//// if(ineqL[i]->type <= 1) { +//// /* Working on a > or >= ineq */ +// +// if(ineq.get_op().equals(">") || ineq.get_op().equals(">=")){ +// // Working on a > or >= ineq +// +//// if(s->r->bound[p-nevents].current > 0) { +// +// // If the rate is positive. +// if(getCurrentRate(contVar) > 0){ +// +//// if(s->m->state[ineqL[i]->signal]=='1') { +// if(ineqValue != 0){ +//// if(s->z->matrix[zoneP][0] < +//// chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 1a\n"); +////#endif +//// +////#ifdef __LHPN_WARN__ +//// warn("checkPreds: Impossible case 1.\n"); +////#endif +//// newMin = s->z->matrix[zoneP][0]; +// +// if(getDbmEntry(0, contVar.get_transitionIndex()) +// < chkDiv(ineq.getConstant(), getCurrentRate(contVar), false)){ +// // CP: case 1a. +// newMin = getDbmEntry(0, contVar.get_transitionIndex()); +// System.err.println("maxAdvance: Impossible case 1."); +// } +// +//// } +//// else if((-1)*s->z->matrix[0][zoneP] > +//// chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 2a\n"); +////#endif +//// newMin = chkDiv(events[p]->urange, +//// s->r->bound[p-nevents].current,'F'); +//// } +// else if ((-1)*getDbmEntry(contVar.get_transitionIndex(),0) +// > chkDiv(ineq.getConstant(), +// getCurrentRate(contVar), false)){ +// // CP : case 2a +// newMin = INFINITY; +// +// } +// +//// else { +//// /* straddle case */ +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 3a\n"); +////#endif +//// newMin = chkDiv(events[p]->urange, +//// s->r->bound[p-nevents].current,'F'); +//// } +//// } +// else{ +// // Straddle case +// // CP : case 3a +// newMin = INFINITY; +// } +// } +// else{ +//// else { +//// if(s->z->matrix[zoneP][0] < +//// chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 4a -- min: %d\n",chkDiv(ineqL[i]->constant,s->r->bound[p-nevents].current,'F')); +////#endif +//// newMin = chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F'); +//// } +// if(getDbmEntry(contVar.get_transitionIndex(), 0) +// < chkDiv(ineq.getConstant(), getCurrentRate(contVar), false)){ +// // CP: case 4a -- min +// newMin = chkDiv(ineq.getConstant(), +// getCurrentRate(contVar), false); +// } +// +//// else if((-1)*s->z->matrix[0][zoneP] > +//// chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 5a\n"); +////#endif +////#ifdef __LHPN_WARN__ +//// warn("checkPreds: Impossible case 3.\n"); +////#endif +//// newMin = s->z->matrix[zoneP][0]; +//// } +// else if((-1)*getDbmEntry(contVar.get_transitionIndex(),0) +// < chkDiv(ineq.getConstant(), getCurrentRate(contVar), false)){ +// // Impossible case 3. +// newMin = getDbmEntry(0, contVar.get_transitionIndex()); +// System.err.print("maxAdvance : Impossible case 3."); +// } +// +//// else { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 6a -- min: %d\n",s->z->matrix[zoneP][0]); +////#endif +//// /* straddle case */ +//// newMin = s->z->matrix[zoneP][0]; +//// } +//// } +//// } +// else{ +// // CP : cas 6a +// // straddle case +// newMin = getDbmEntry(0,contVar.get_transitionIndex()); +// } +// } +// } +// +//// else { +//// /* warp <= 0 */ +// +// else{ +// // warp <= 0. +// +//// if(s->m->state[ineqL[i]->signal]=='1') { +// +// if( ineqValue != 1){ +// +//// if(s->z->matrix[0][zoneP] < +//// (-1)*chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 7a\n"); +////#endif +////#ifdef __LHPN_WARN__ +//// warn("checkPreds: Impossible case 2.\n"); +////#endif +//// newMin = s->z->matrix[zoneP][0]; +//// } +// +// if(getDbmEntry(contVar.get_transitionIndex(),0) +// < (-1)*chkDiv(ineq.getConstant(), +// getCurrentRate(contVar), false)){ +// // CP: case 7a. +// newMin = getDbmEntry(0,contVar.get_transitionIndex()); +// System.err.println("Warining: impossible case 2a found."); +// } +// +//// else if((-1)*s->z->matrix[zoneP][0] > +//// (-1)*chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 8a\n"); +////#endif +//// newMin = chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F'); +//// } +// +// else if((-1)*getDbmEntry(0, contVar.get_transitionIndex()) +// < (-1)*chkDiv(ineq.getConstant(), +// getCurrentRate(contVar), false)){ +// // Impossible case 8a. +// newMin = chkDiv(ineq.getConstant(), +// getCurrentRate(contVar), false); +// } +// +//// else { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 9a\n"); +////#endif +//// /* straddle case */ +//// newMin = s->z->matrix[zoneP][0]; +//// } +//// } +// +// else{ +// // straddle case +// newMin = getDbmEntry(0, contVar.get_transitionIndex()); +// } +// +// } +//// else { +// +// else{ +// +//// if(s->z->matrix[0][zoneP] < +//// (-1)*chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 10a\n"); +////#endif +//// newMin = chkDiv(events[p]->lrange, +//// s->r->bound[p-nevents].current,'F'); +//// } +// +// if(getDbmEntry(contVar.get_transitionIndex(),0) +// < (-1)*chkDiv(ineq.getConstant(), +// getCurrentRate(contVar), false)){ +// // CP: case 10a. +// newMin = INFINITY; +// } +// +// +//// else if((-1)*s->z->matrix[zoneP][0] > +//// (-1)*chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 11a\n"); +//// printf("z=%d c=%d b=%d\n", +//// s->z->matrix[zoneP][0], +//// ineqL[i]->constant, +//// s->r->bound[p-nevents].current); +//// +////#endif +////#ifdef __LHPN_WARN__ +//// warn("checkPreds: Impossible case 4.\n"); +////#endif +//// newMin = s->z->matrix[zoneP][0]; +//// } +// +// else if((-1)*getDbmEntry(0, contVar.get_transitionIndex()) +// < (-1)*chkDiv(ineq.getConstant(), +// getCurrentRate(contVar), false)){ +// // CP: case 7a. +// newMin = getDbmEntry(0,contVar.get_transitionIndex()); +// System.err.println("maxAdvance : Impossible case 4."); +// } +// +//// else { +//// /* straddle case */ +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 12a\n"); +////#endif +//// newMin = chkDiv(events[p]->lrange, +//// s->r->bound[p-nevents].current,'F'); +//// } +//// } +//// } +//// } +// else{ +// // straddle case +// newMin = INFINITY; +// } +// } +// } +// } +//// else { +//// /* Working on a < or <= ineq */ +// else{ +// // Working on a < or <= ineq +// +//// if(s->r->bound[p-nevents].current > 0) { +// +// if(getUpperBoundForRate(contVar) > 0){ +// +//// if(s->m->state[ineqL[i]->signal]=='1') { +// +// if(ineqValue != 0){ +// +//// if(s->z->matrix[zoneP][0] < +//// chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 1b -- min: %d\n",chkDiv(ineqL[i]->constant,s->r->bound[p-nevents].current,'F')); +////#endif +//// newMin = chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F'); +//// } +// +// if(getDbmEntry(0, contVar.get_transitionIndex()) +// < (-1)*chkDiv(ineq.getConstant(), +// getCurrentRate(contVar), false)){ +// // CP: case 1b -- min. +// newMin = chkDiv(ineq.getConstant(), +// getCurrentRate(contVar), false); +// } +// +// +//// else if((-1)*s->z->matrix[0][zoneP] > +//// chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 2b\n"); +////#endif +////#ifdef __LHPN_WARN__ +//// warn("checkPreds: Impossible case 5.\n"); +////#endif +//// newMin = chkDiv(events[p]->urange, +//// s->r->bound[p-nevents].current,'F'); +//// } +// +// if((-1)*getDbmEntry(contVar.get_transitionIndex(), 0) +// < chkDiv(ineq.getConstant(), getCurrentRate(contVar),false)){ +// // CP: case 2b. +// newMin = INFINITY; +// System.err.println("Warning : Impossible case 5."); +// } +// +//// else { +//// /* straddle case */ +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 3b -- min: %d\n",s->z->matrix[zoneP][0]); +////#endif +//// newMin = s->z->matrix[zoneP][0]; +//// } +//// } +// else{ +// //straddle case +// newMin = getDbmEntry(0,contVar.get_transitionIndex()); +// } +// +// } +//// else { +// +// else{ +// +//// if(s->z->matrix[zoneP][0] < +//// chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 4b\n"); +////#endif +////#ifdef __LHPN_WARN__ +//// warn("checkPreds: Impossible case 7.\n"); +////#endif +//// newMin = s->z->matrix[zoneP][0]; +//// } +// +// if(getDbmEntry(0, contVar.get_transitionIndex()) +// < chkDiv(ineq.getConstant(), +// getCurrentRate(contVar), false)){ +// // CP: case 4b. +// newMin = getDbmEntry(0, contVar.get_transitionIndex()); +// System.err.println("maxAdvance : Impossible case 7."); +// } +// +//// else if((-1)*s->z->matrix[0][zoneP] > +//// chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 5b\n"); +////#endif +//// newMin = chkDiv(events[p]->urange, +//// s->r->bound[p-nevents].current,'F'); +//// } +// +// else if((-1)*getDbmEntry(contVar.get_transitionIndex(), 0) +// < chkDiv(ineq.getConstant(), +// getCurrentRate(contVar), false)){ +// // CP: case 5b. +// newMin = INFINITY; +// } +//// else { +//// /* straddle case */ +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 6b\n"); +////#endif +//// newMin = chkDiv(events[p]->urange, +//// s->r->bound[p-nevents].current,'F'); +//// } +//// } +//// } +// else{ +// // straddle case +// // CP : case 6b +// newMin = INFINITY; +// } +// } +// +// } +//// else { +//// /* warp <= 0 */ +// +// else { +// // warp <=0 +// +//// if(s->m->state[ineqL[i]->signal]=='1') { +// if(ineqValue != 0){ +// +//// if(s->z->matrix[0][zoneP] < +//// (-1)*chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 7b\n"); +////#endif +//// newMin = chkDiv(events[p]->lrange, +//// s->r->bound[p-nevents].current,'F'); +//// } +// +// if(getDbmEntry(contVar.get_transitionIndex(), 0) +// < (-1)*chkDiv(ineq.getConstant(), +// getCurrentRate(contVar), false)){ +// // CP: case 7b. +// newMin = INFINITY; +// } +// +//// else if((-1)*s->z->matrix[zoneP][0] > +//// (-1)*chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 8b\n"); +////#endif +////#ifdef __LHPN_WARN__ +//// warn("checkPreds: Impossible case 8.\n"); +////#endif +//// newMin = s->z->matrix[zoneP][0]; +//// } +// +// else if((-1)*getDbmEntry(0, contVar.get_transitionIndex()) +// < (-1)*chkDiv(ineq.getConstant(), +// getCurrentRate(contVar), false)){ +// // CP: case 8b. +// newMin = getDbmEntry(0, contVar.get_transitionIndex()); +// System.err.println("Warning : Impossible case 8."); +// } +// +//// else { +//// /* straddle case */ +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 9b\n"); +////#endif +//// newMin = chkDiv(events[p]->lrange, +//// s->r->bound[p-nevents].current,'F'); +//// } +// else { +// // straddle case +// // CP: case 9b. +// newMin = INFINITY; +// } +//// } +// +// } +// +//// else { +// +// else { +// +//// if(s->z->matrix[0][zoneP] < +//// chkDiv((-1)*ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 10b\n"); +//// printf("zone: %d const: %d warp: %d chkDiv: %d\n",s->z->matrix[0][zoneP],ineqL[i]->constant,s->r->bound[p-nevents].current,chkDiv((-1)*ineqL[i]->constant,s->r->bound[p-nevents].current,'F')); +////#endif +////#ifdef __LHPN_WARN__ +//// warn("checkPreds: Impossible case 6.\n"); +////#endif +//// newMin = s->z->matrix[zoneP][0]; +//// } +// +// if(getDbmEntry(contVar.get_transitionIndex(),0) +// < (-1)*chkDiv(ineq.getConstant(), +// getCurrentRate(contVar), false)){ +// // CP: case 10b. +// newMin = getDbmEntry(0,contVar.get_transitionIndex()); +// System.err.println("Warning : Impossible case 6"); +// } +// +//// else if((-1)*s->z->matrix[zoneP][0] > +//// (-1)*chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 11b\n"); +////#endif +//// newMin = chkDiv(ineqL[i]->constant, +//// s->r->bound[p-nevents].current,'F'); +//// } +// else if((-1)*getDbmEntry(0,contVar.get_transitionIndex()) +// < (-1)*chkDiv(ineq.getConstant(), +// getCurrentRate(contVar),false)){ +// // CP: case 7b. +// newMin = chkDiv(ineq.getConstant(), getCurrentRate(contVar),false); +// } +// +// +//// else { +//// /* straddle case */ +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("CP:case 12b\n"); +////#endif +//// newMin = s->z->matrix[zoneP][0]; +//// } +// +// +// else { +// // straddle case +// // CP : case 12b +// newMin = getDbmEntry(0, contVar.get_transitionIndex()); +// } +// +//// } +//// } +//// } +//// } +//// if(newMin < min) { +//// min = newMin; +//// } +// +// } +// } +// } +// // Check if the value can be lowered. +// if(newMin < min){ +// min = newMin; +// } +// } +////} +//// +////#ifdef __LHPN_PRED_DEBUG__ +////printf("Min leaving checkPreds for %s: %d\n",events[p]->event,min); +////#endif +////return min; +////} +// +// return min; +// } + + /* (non-Javadoc) + * @see java.lang.Object#clone() + */ + @Override + public Zone clone() + { + // TODO: Check if finished. + + Zone clonedZone = new Zone(); + + clonedZone._matrix = new int[this.matrixSize()][this.matrixSize()]; + + for(int i=0; i adjustedColumns = new HashSet(); + + boolean needsAdjusting = false; + + // Restrict the variables according to each of the inequalities in the eventSet. + for(Event e : eventSet){ + // Get the inequality. + InequalityVariable iv = e.getInequalityVariable(); + + // Extract the variable. I will assume the inequality only depends on a single + // variable. + Variable x = iv.getContVariables().get(0); + + // Extract the index. + int lpnIndex = iv.get_lpn().getLpnIndex(); + + // Extract the variable index. +// DualHashMap variableIndexMap = _lpnList[lpnIndex].getVarIndexMap(); + DualHashMap variableIndexMap = _lpnList[lpnIndex].getContinuousIndexMap(); + int variableIndex = variableIndexMap.getValue(x.getName()); + + // Package it up for referencing. +// LPNContinuousPair ltContPair = new LPNContinuousPair(lpnIndex, variableIndex, 0); + LPNContinuousPair ltContPair = new LPNContinuousPair(lpnIndex, variableIndex); + + + // Need the current rate for the variable, grab the stored LPNContinuousPair. + int zoneIndex = Arrays.binarySearch(_indexToTimerPair, ltContPair); + if(zoneIndex > 0){ + ltContPair = (LPNContinuousPair) _indexToTimerPair[zoneIndex]; + } + + + //setDbmEntry(zoneIndex, 0, -ContinuousUtilities.chkDiv(iv.getConstant(), ltContPair.getCurrentRate(), true)); + + // Perform the restricting. + needsAdjusting = needsAdjusting | restrictContinuous(ltContPair, iv.getConstant()); + + if(needsAdjusting){ + adjustedColumns.add(ltContPair); + } + } + + // If one of the continuous variables has been moved forward, the other colmns + // need to be adjusted to keep a consistent zone. + if(needsAdjusting){ + // At least one of the continuous variables has been moved forward, + // so se need to ajust the bounds to keep a consistent zone. + for(int i=1; i<_indexToTimerPair.length; i++){ + + LPNTransitionPair ltpair = _indexToTimerPair[i]; + + if(adjustedColumns.contains(ltpair)){ + // This continuous variables already had the upper bound + // adjusted. + continue; + } + // Add one to the upper bounds. + setDbmEntry(0, i, getDbmEntry(0, i)+1); + } + } + } + + /** + * Returns a zone that is the result from restricting the this zone according to a list of firing event inequalities. + * @param eventSet + * The list of inequalities that are firing. + * @return + * The new zone that is the result of restricting this zone according to the firing of the inequalities + * in the eventSet. + */ + @Override + public Zone getContinuousRestrictedZone(EventSet eventSet, State[] localStates){ + // Make a new copy of the zone. + Zone z = this.clone(); + + if(eventSet == null){ + return z; + } + + z.restrictContinuous(eventSet); + +// z.advance(localStates); +// +// z.recononicalize(); + + return z; + } + + /** + * The list of enabled timers. + * @return + * The list of all timers that have reached their lower bounds. + */ + @Override + public List getEnabledTransitions() + { + ArrayList enabledTransitions = new ArrayList(); + + // Check if the timer exceeds its lower bound staring with the first nonzero + // timer. + for(int i=1; i<_indexToTimerPair.length; i++) + { + if(getDbmEntry(0, i) >= -1 * getLowerBoundbydbmIndex(i)) + { + enabledTransitions.add(_lpnList[_indexToTimerPair[i].get_lpnIndex()] + .getTransition(_indexToTimerPair[i].get_transitionIndex())); + } + } + + return enabledTransitions; + } + + /** + * Gives the list of enabled transitions associated with a particular LPN. + * @param LpnIndex + * The Index of the LPN the Transitions are a part of. + * @return + * A List of the Transitions that are enabled in the LPN given by the index. + */ + @Override + public List getEnabledTransitions(int LpnIndex){ + ArrayList enabledTransitions = new ArrayList(); + + // Check if the timer exceeds its lower bound staring with the first nonzero + // timer. + for(int i=1; i<_indexToTimerPair.length; i++) + { + if(getDbmEntry(0, i) >= -1 * getLowerBoundbydbmIndex(i)) + { + LPNTransitionPair ltPair = _indexToTimerPair[i]; + + if( ltPair.get_lpnIndex() == LpnIndex){ + + enabledTransitions.add(_lpnList[ltPair.get_lpnIndex()] + .getTransition(ltPair.get_transitionIndex())); + } + } + } + + return enabledTransitions; + } + + /** + * Find the next possible events. + * + * @param LpnIndex + * The index of the LPN that is of interest. + * @param localState + * The state associated with the LPN indexed by LpnIndex. + * @return + * LpnTranList is populated with a list of + * EventSets pertaining to the LPN with index LpnIndex. An EventSet can + * either contain a transition to + * fire or set of inequalities to change sign. + */ + @Override + public LpnTranList getPossibleEvents(int LpnIndex, State localState){ + LpnTranList result = new LpnTranList(); + + // Look through the timers and continuous variables. For the timers + // determine if they are ready to fire. For the continuous variables, + // look up the associated inequalities and see if any of them are ready + // to fire. +// for(LPNTransitionPair ltPair : _indexToTimerPair){ +// +// } + + // We do not need to consider the zero timer, so start the + // for loop at i=1 and not i=0. + for(int i=1; i<_indexToTimerPair.length; i++){ + LPNTransitionPair ltPair = _indexToTimerPair[i]; + + // The enabled events are grouped with the LPN that they affect. So if + // this pair does not belong to the current LPN under consideration, skip + // processing it. + if(ltPair.get_lpnIndex() != LpnIndex){ + continue; + } + + // If the index refers to a timer (and not a continuous variable) and has exceeded its lower bound, + // then add the transition. + if(!(ltPair instanceof LPNContinuousPair)){ + //result.add(_lpnList[ltPair.get_lpnIndex()].getTransition(ltPair.get_transitionIndex())); + + // The index refers to a timer. Now check if time has advanced + // far enough for the transition to fire. + if(getDbmEntry(0, i) >= -1 * getLowerBoundbydbmIndex(i)){ + + Event e = new Event(_lpnList[ltPair.get_lpnIndex()].getTransition(ltPair.get_transitionIndex())); + result = addSetItem(this, result, e, localState); + } + } + + else{ + // The index refers to a continuous variable. + // First check for a rate change event. + LPNContinuousPair ltContPair = + ((LPNContinuousPair) ltPair).clone(); + + IntervalPair ratePair = getRateBounds(ltContPair); + +// if(!ratePair.singleValue() +// && (ltContPair.getCurrentRate() == ratePair.getSmallestRate())){ +// // The rate represents a range of rates and no rate change +// // event has occured. +// if(ratePair.containsZero()){ +// // The rate contians zero, so we need to add two rate +// // events: one for the lower bound and one for the upper +// // bound. +// LPNContinuousPair otherltContPair = ltContPair.clone(); +// +// ltContPair.setCurrentRate(ratePair.get_LowerBound()); +// otherltContPair.setCurrentRate(ratePair.get_UpperBound()); +// +// // Create the events. +// Event lowerRateChange = new Event(ltContPair); +// Event upperRateChange = new Event(otherltContPair); +// +// // Add them to the result set. +// result = addSetItem(result, lowerRateChange, localState); +// result = addSetItem(result, upperRateChange, localState); +// } +// else{ +// ltContPair.setCurrentRate(ratePair.getLargestRate()); +// result = addSetItem(result, +// new Event(ltContPair), localState); +// } +// } + + result = createRateEvents(this, ltContPair, ratePair, result, localState); + + // Check all the inequalities for inclusion. + Variable contVar = _lpnList[ltPair.get_lpnIndex()] + .getContVar(ltPair.get_transitionIndex()); + + if(contVar.getInequalities() != null){ + for(InequalityVariable iv : contVar.getInequalities()){ + + // Check if the inequality can change. + if(ContinuousUtilities.inequalityCanChange(this, iv, localState)){ + result = addSetItem(this, result, new Event(iv), localState); + } + } + } + + } + } + + // Check the rate zero variables for possible rate change events. + for(LPNContAndRate lcrPair : _rateZeroContinuous.keySet()){ + // Get the reference object: + LPNContinuousPair ltContPair = lcrPair.get_lcPair(); + + // Extract the range of rates. + IntervalPair ratePair = lcrPair.get_rateInterval(); + + result = createRateEvents(this, ltContPair, ratePair, result, localState); + + } + + return result; + } + + public static LpnTranList createRateEvents(Equivalence Z, LPNContinuousPair ltContPair, IntervalPair ratePair, + LpnTranList result, State localState){ + +// ltContPair = ltContPair.clone(); +// +// if(!ratePair.singleValue() +// && (ltContPair.getCurrentRate() == ratePair.getSmallestRate())){ +// // The rate represents a range of rates and no rate change +// // event has occured. +//// if(ratePair.containsZero()){ +// if(ratePair.strictlyContainsZero()){ +// // The rate contians zero, so we need to add two rate +// // events: one for the lower bound and one for the upper +// // bound. +// LPNContinuousPair otherltContPair = ltContPair.clone(); +// +// ltContPair.setCurrentRate(ratePair.get_LowerBound()); +// otherltContPair.setCurrentRate(ratePair.get_UpperBound()); +// +// // Create the events. +// Event lowerRateChange = new Event(ltContPair); +// Event upperRateChange = new Event(otherltContPair); +// +// // Add them to the result set. +// result = addSetItem(result, lowerRateChange, localState); +// result = addSetItem(result, upperRateChange, localState); +// } +// else{ +// ltContPair.setCurrentRate(ratePair.getLargestRate()); +// result = addSetItem(result, +// new Event(ltContPair), localState); +// } +// } + + /* + * Let [a,b] be the current range of rates for a given variable. + * If a>=0, then we set the rate to b originally. + * So if the current rate is b, then we have a rate change event to a. + * + * If b<=0, then we set the rate to a originially. + * So if the current rate is a, then we have a rate change event to b. + * + * The final case to consider is when a < 0 and b > 0. If the current + * rate is b, we allow rate changes to either a or 0. If the current + * rate is a, we allow a rate change to zero. + */ + + if(ratePair.singleValue()){ + // Rates that are not a range do not generate rate change events. + return result; + } + + ltContPair = ltContPair.clone(); + + if(ratePair.get_LowerBound() >= 0){ + if(ltContPair.getCurrentRate() == ratePair.get_UpperBound()){ + ltContPair.setCurrentRate(ratePair.get_LowerBound()); + result = addSetItem(Z, result, new Event(ltContPair), localState); + } + } + else if(ratePair.get_UpperBound()<=0){ + if(ltContPair.getCurrentRate() == ratePair.get_LowerBound()){ + ltContPair.setCurrentRate(ratePair.get_UpperBound()); + result = addSetItem(Z, result, new Event(ltContPair), localState); + } + } + // At this point, lower bound < 0 < upper bound. + else{ + if(ltContPair.getCurrentRate() == ratePair.get_UpperBound()){ + // No rate change events have ocurred. So we allow one for zero + // and the lower bounds rate. + LPNContinuousPair ltContPairOther = ltContPair.clone(); + + ltContPair.setCurrentRate(0); + ltContPairOther.setCurrentRate(ratePair.get_LowerBound()); + + result = addSetItem(Z, result, new Event(ltContPair), localState); + result = addSetItem(Z, result, new Event(ltContPairOther), localState); + } + else if(ltContPair.getCurrentRate() == ratePair.get_LowerBound()){ + // The rate has change to the lower bound. Allow one rate + // change to zero. + ltContPair.setCurrentRate(0); + + result = addSetItem(Z, result, new Event(ltContPair), localState); + } + + } + + + return result; + } + + /** + * Adds or removes items as appropriate to update the current + * list of possible events. Note the type LpnTranList extends + * LinkedList. The type EventSet extends transition + * specifically so that objects of EventSet type can be place in + * this list. + * @param EventList + * The list of possible events. + */ + public static LpnTranList addSetItem(Equivalence Z, LpnTranList E, Event e, State s){ +// void lhpnAddSetItem(eventSets &E,lhpnEventADT e,ineqList &ineqL,lhpnZoneADT z, +// lhpnRateADT r,eventADT *events,int nevents, +// lhpnStateADT cur_state) +//{ +//int rv1l,rv1u,rv2l,rv2u,iZ,jZ; + + // Note the LPNTranList plays the role of the eventSets. + + int rv1l=0, rv1u=0, rv2l=0, rv2u=0, iZ, jZ; + +// +//#ifdef __LHPN_TRACE__ +//printf("lhpnAddSetItem:begin()\n"); +//#endif +//#ifdef __LHPN_ADD_ACTION__ +//printf("Event sets entering:\n"); +//printEventSets(E,events,ineqL); +//printf("Examining event: "); +//printLhpnEvent(e,events,ineqL); +//#endif +//eventSet* eSet = new eventSet(); +//eventSets* newE = new eventSets(); +//bool done = false; +//bool possible = true; +//eventSets::iterator i; + + // Create the new LpnTranlist for holding the events. + EventSet eSet = new EventSet(); + LpnTranList newE = new LpnTranList(); + boolean done = false; + boolean possible = true; + +// +//if ((e->t == -1) && (e->ineq == -1)) { + if(e.isRate()){ +//eSet->insert(e); + eSet.add(e); +//newE->push_back(*eSet); + + // I believe that I should actually copy over the old list + // and then add the new event set. + newE = E.copy(); + newE.addLast(eSet); +//E.clear(); +//E = *newE; + + // The previous two commands act to pass the changes of E + // back out of the functions. So returning the new object + // is suficient. + +//#ifdef __LHPN_ADD_ACTION__ +//printf("Event sets leaving:\n"); +//printEventSets(E,events,ineqL); +//#endif +//#ifdef __LHPN_TRACE__ +//printf("lhpnAddSetItem:end()\n"); +//#endif +//return; +//} + return newE; + + } +//if (e->t == -1) { + if(e.isInequality()){ +//ineq_update(ineqL[e->ineq],cur_state,nevents); + + // Is this necessary, or even correct to update the inequalities. + //System.out.println("Note the inequality is not being updated before in addSetItem"); + + // In this case the Event e represents an inequality. + InequalityVariable ineq = e.getInequalityVariable(); + +//rv2l = chkDiv(-1 * ineqL[e->ineq]->constant, +// r->bound[ineqL[e->ineq]->place-nevents].current,'C'); +//rv2u = chkDiv(ineqL[e->ineq]->constant, +// r->bound[ineqL[e->ineq]->place-nevents].current,'C'); +//iZ = getIndexZ(z,-2,ineqL[e->ineq]->place); + + // Need to extract the rate. + // To do this, I'll create the indexing object. + Variable v = ineq.getContVariables().get(0); + // Find the LPN. + int lpnIndex = ineq.get_lpn().getLpnIndex(); + +// int varIndex = _lpnList[lpnIndex]. +// getContinuousIndexMap().getValue(v.getName()); + + int varIndex = Z.getVarIndex(lpnIndex, v.getName()); + + // Package it all up. +// LPNTransitionPair ltPair = +// new LPNTransitionPair(lpnIndex, varIndex, false); + // Note : setting the rate is not necessary since + // this is only being used as aan index. +// LPNContinuousPair ltPair = +// new LPNContinuousPair(lpnIndex, varIndex, 0); + LPNContinuousPair ltPair = new LPNContinuousPair(lpnIndex, varIndex); + + rv2l = ContinuousUtilities.chkDiv(-1*ineq.getConstant(), + Z.getCurrentRate(ltPair), true); + rv2u = ContinuousUtilities.chkDiv(ineq.getConstant(), + Z.getCurrentRate(ltPair), true); +// iZ = Arrays.binarySearch(_indexToTimerPair, ltPair); + iZ = Z.getIndexByTransitionPair(ltPair); +//} else { + } + else{ +//iZ = getIndexZ(z,-1,e->t); +//} + // In this case, the event is a transition. + Transition t = e.getTransition(); + + int lpnIndex = t.getLpn().getLpnIndex(); + + int tranIndex = t.getIndex(); + + // Package the results. +// LPNTransitionPair ltPair = new LPNTransitionPair(lpnIndex, tranIndex, true); + LPNTransitionPair ltPair = new LPNTransitionPair(lpnIndex, tranIndex); + +// iZ = Arrays.binarySearch(_indexToTimerPair, ltPair); + iZ = Z.getIndexByTransitionPair(ltPair); + } + + +//for(i=E.begin();i!=E.end()&&!done;i++) { + + // Recall that E contains the events sets which are inherited from the Transition class + // so they can be placed in an LpnTranList. So consider each event set. + for(Transition es : E){ + + if(!(es instanceof EventSet)){ + // This collection should contain event sets, not transitions. + throw new IllegalArgumentException("The eventSet was a Transition object not an EventSet object."); + } + + EventSet eventSet = (EventSet) es; + + if(done){ + // Copy any remaining sets into newE. + newE.add(eventSet.clone()); + break; + } + +//eventSet* workSet = new eventSet(); +//*workSet = copyEventSet(*i,events,ineqL); + + EventSet workSet = eventSet.clone(); + +//for(eventSet::iterator j=workSet->begin();j!=workSet->end();j++) { + + + // Get an iterator for the elements in the workset. + //Iterator workSetIterator = workSet.iterator(); + //for(Event oldEvent : workSet){ + //while(workSetIterator.hasNext()){ + for(Event oldEvent : eventSet){ + //Event oldEvent = workSetIterator.next(); + +// if (((*j)->t == -1) && ((*j)->ineq == -1)) continue; + + // For matching code with atacs, note that oldEvent is 'j'. + if(oldEvent.isRate()){ + continue; + } + +// if ((*j)->t == -1) { + + if(oldEvent.isInequality()){ + + +//ineq_update(ineqL[(*j)->ineq],cur_state,nevents); +// rv1l = chkDiv(-1 * ineqL[(*j)->ineq]->constant, +// r->bound[ineqL[(*j)->ineq]->place-nevents].current,'C'); +// rv1u = chkDiv(ineqL[(*j)->ineq]->constant, +// r->bound[ineqL[(*j)->ineq]->place-nevents].current,'C'); +// jZ = getIndexZ(z,-2,ineqL[(*j)->ineq]->place); +// } else { + + // Again, is it necessary to do an update here? + //System.out.println("Note the inequality is not being updated before in addSetItem"); + + // In this case the Event oldEvent represents an inequality. + InequalityVariable ineq = oldEvent.getInequalityVariable(); + + //Extract variable. + Variable v = ineq.getContVariables().get(0); + // Find the LPN. + int lpnIndex = ineq.get_lpn().getLpnIndex(); + +// int varIndex = _lpnList[lpnIndex]. +// getContinuousIndexMap().getValue(v.getName()); + + int varIndex = Z.getVarIndex(lpnIndex, v.getName()); + + // Package it all up. +// LPNTransitionPair ltPair = +// new LPNTransitionPair(lpnIndex, varIndex, false); + // Note : setting the rate is not necessary since this is + // only being used as an index. +// LPNContinuousPair ltPair = +// new LPNContinuousPair(lpnIndex, varIndex, 0); + LPNContinuousPair ltPair = + new LPNContinuousPair(lpnIndex, varIndex); + + rv1l = ContinuousUtilities.chkDiv( + -1 * oldEvent.getInequalityVariable().getConstant(), + Z.getCurrentRate(ltPair), true); + rv1u = ContinuousUtilities.chkDiv( + oldEvent.getInequalityVariable().getConstant(), + Z.getCurrentRate(ltPair), true); + +// jZ = Arrays.binarySearch(_indexToTimerPair, ltPair); + + jZ = Z.getIndexByTransitionPair(ltPair); + + } + else{ + +// jZ = getIndexZ(z,-1,(*j)->t); +// } + // In this case, the event is a transition. + Transition t = oldEvent.getTransition(); + + // Create the indexing object. (See the Abstraction Function protion at the + // top of the class for more details.) + int lpnIndex = t.getLpn().getLpnIndex(); + + int tranIndex = t.getIndex(); + + // Package the results. +// LPNTransitionPair ltPair = new LPNTransitionPair(lpnIndex, tranIndex, true); + LPNTransitionPair ltPair = new LPNTransitionPair(lpnIndex, tranIndex); + +// jZ = Arrays.binarySearch(_indexToTimerPair, ltPair); + + jZ = Z.getIndexByTransitionPair(ltPair); + } + +// /* Both actions are predicate changes */ +// if((e->t == -1) && ((*j)->t == -1)) { + + // Both actions are predicate changes. + if(e.isInequality() && oldEvent.isInequality()){ + +// /* Both predicates are on the same variable */ +// if(ineqL[(*j)->ineq]->place == ineqL[e->ineq]->place) { + + // Extract the variable lists. + ArrayList newList = e.getInequalityVariable() + .getContVariables(); + ArrayList oldList = oldEvent.getInequalityVariable() + .getContVariables(); + + // Issue a warning if one of the lists has more than a single + // variable. + if(newList.size() > 1 && oldList.size() > 1){ + System.err.println("Warning: One of the inequalities " + e + + " " + oldEvent + " refers to more than one variable"); + } + + // Both inequalities are on the same variables. + if(newList.get(0).equals(oldList.get(0))){ + +// if (rv1l > rv2l) { +//#ifdef __LHPN_ADD_ACTION__ +// printf("Add action case 1a\n"); +//#endif +// possible = false; + + if(rv1l > rv2l){ + possible = false; + } + + +// } else if (rv2l > rv1l) { +//#ifdef __LHPN_ADD_ACTION__ +// printf("Add action case 1b\n"); +// printf("Adding to erase list: \n"); +// printLhpnEvent(*j,events,ineqL); +//#endif +// workSet->erase(*j); + + else if (rv2l > rv1l){ + workSet.remove(oldEvent); + } + +// } else if (rv1u > rv2u) { +//#ifdef __LHPN_ADD_ACTION__ +// printf("Add action case 1c\n"); +// printf("Adding to erase list: \n"); +// printLhpnEvent(*j,events,ineqL); +//#endif +// workSet->erase(*j); + + else if(rv1u > rv2u){ + workSet.remove(oldEvent); + } + +// } else { +//#ifdef __LHPN_ADD_ACTION__ +// printf("Add action case 1d\n"); +//#endif +// workSet->insert(e); +// done = true; + + else{ + workSet.add(e); + done = true; + } + +// } +// +// } + + } + +// /* Predicates are on different variables */ +// else { + + // Inequalities are on different variables. + else { + + // TODO : Check that the indecies must be reversed. I believe + // they do since I think my representation is the transpose + // of atacs. This will affect all the following statements. + + +// if(rv1l > rv2l + z->matrix[iZ][jZ]) { +//#ifdef __LHPN_ADD_ACTION__ +// printf("Add action case 2\n"); +//#endif +// possible = false; + + if(rv1l > rv2l + Z.getDbmEntry(jZ, iZ)){ + possible = false; + } +// } +// else if(rv2l > rv1l + z->matrix[jZ][iZ]) { +//#ifdef __LHPN_ADD_ACTION__ +// printf("Add action case 3\n"); +// printf("Adding to erase list: "); +// printLhpnEvent(*j,events,ineqL); +//#endif +// workSet->erase(*j); +// // workSet->insert(e); + + + else if(rv2l > rv1l + Z.getDbmEntry(iZ, jZ)){ + workSet.remove(oldEvent); + } + +// } +// else if(rv1u > z->matrix[iZ][0] + z->matrix[jZ][iZ]) { +//#ifdef __LHPN_ADD_ACTION__ +// printf("Add action case 4\n"); +// printf("Adding to erase list: \n"); +// printLhpnEvent(*j,events,ineqL); +//#endif +// workSet->erase(*j); +// //workSet->insert(e); + +// else if(rv1u > Z.getDbmEntry(0, iZ) + Z.getDbmEntry(iZ, jZ)){ + else if(rv1u > Z.getUpperBoundTrue(iZ) + Z.getDbmEntry(iZ, jZ)){ + workSet.remove(oldEvent); + } + +// } +// else if(rv2u > z->matrix[jZ][0] + z->matrix[iZ][jZ]) { +//#ifdef __LHPN_ADD_ACTION__ +// printf("Add action case 5\n"); +//#endif +// possible = false; + +// else if (rv2u > Z.getDbmEntry(0, jZ) + Z.getDbmEntry(jZ, iZ)){ + else if (rv2u > Z.getUpperBoundTrue(jZ) + Z.getDbmEntry(jZ, iZ)){ + possible = false; + } + +// } +// else if((rv1l == rv2l + z->matrix[iZ][jZ]) && +// (rv2l == rv1l + z->matrix[jZ][iZ]) && +// (rv1u == rv2u + z->matrix[jZ][iZ]) && +// (rv2u == rv1u + z->matrix[iZ][jZ])) { +// workSet->insert(e); +// done = true; +//#ifdef __LHPN_ADD_ACTION__ +// printf("Add action case 6\n"); + + else if(rv1l == rv2l + Z.getDbmEntry(jZ, iZ) && + rv2l == rv1l + Z.getDbmEntry(iZ, jZ) && + rv1u == rv2u + Z.getDbmEntry(iZ, jZ) && + rv2u == rv1u + Z.getDbmEntry(jZ, iZ)){ + + workSet.add(e); + + } + +//#endif +// } +// } + + } + + } +// /* New action is predicate change, old is transition firing (case 3) */ +// } else if((e->t == -1) && ((*j)->t != -1)) { + + // New action is an inequality and the old even tis a transition (case 3). + else if (e.isInequality() && oldEvent.isTransition()){ + +// if (rv2l > -events[(*j)->t]->lower + z->matrix[jZ][iZ]) { +//#ifdef __LHPN_ADD_ACTION__ +// printf("Add action case 6\n"); +// printf("Adding to erase list: \n"); +// printLhpnEvent(*j,events,ineqL); +//#endif +// workSet->erase(*j); + + if(rv2l > -1* Z.getLowerBoundbyTransition(e.getTransition()) + Z.getDbmEntry(iZ, jZ)){ + //Probably can change this to refer directly to the zone. + workSet.remove(oldEvent); + } + +// } else if (rv2u > z->matrix[jZ][0] + z->matrix[iZ][jZ]) { +//#ifdef __LHPN_ADD_ACTION__ +// printf("Add action case 7\n"); +//#endif +// possible = false; + +// else if(rv2u > Z.getDbmEntry(0, jZ) + Z.getDbmEntry(jZ, iZ)){ + else if(rv2u > Z.getUpperBoundTrue(jZ) + Z.getDbmEntry(jZ, iZ)){ + possible = false; + } + +// } + } + + +// /* TODO: One more ugly case, is it needed? */ +// /* New action is transition firing, old is predicate change (case 4) */ +// } else if((e->t != -1) && ((*j)->t == -1)) { + + // New event is a transition firing, old event is an inequality change (case 4). + else if(e.isTransition() && oldEvent.isInequality()){ + +// if (rv1l > (((-1)*(events[e->t]->lower)) + z->matrix[iZ][jZ])) { +//#ifdef __LHPN_ADD_ACTION__ +// printf("Add action case 8\n"); +//#endif +// possible = false; + + if(rv1l > (-1) * Z.getLowerBoundbyTransition(e.getTransition()) + Z.getDbmEntry(jZ, iZ)){ + possible = false; + } + +// } else if (rv1u > z->matrix[iZ][0] + z->matrix[jZ][iZ]) { +//#ifdef __LHPN_ADD_ACTION__ +// printf("Add action case 9\n"); +// printf("Adding to erase list: \n"); +// printLhpnEvent(*j,events,ineqL); +//#endif +// workSet->erase(*j); + + // Real one: fix the getting of the upper and lower bounds. Done +// else if (rv1u > Z.getDbmEntry(0, iZ) + Z.getDbmEntry(iZ, jZ)){ + else if (rv1u > Z.getUpperBoundTrue(iZ) + Z.getDbmEntry(iZ, jZ)){ + workSet.remove(oldEvent); + } + +// } +// /* TODO: one more ugly case, is it needed? */ +// } +//} + // I guess this one wasn't needed since it is not found in atacs. + + } + } + +//if (!(workSet->empty())) { +// newE->pusph_back(*workSet); +//} +//} + + if(!(workSet.isEmpty())){ + newE.add(workSet); + } + + } + +//#ifdef __LHPN_ADD_ACTION__ +//printf("At new for loop...\n"); +//#endif +//for(;i!=E.end();i++) { +//eventSet* addSet = new eventSet(); +//*addSet = copyEventSet(*i,events,ineqL); +//newE->push_back(*addSet); +//} + + // This part of the code is essentially copying the all the old event set into the new event set. + // There might be a way around doing this by working directly on the set to begin with. + // Moved to being done at the begining of the previous block. +// for(Transition T : E){ +// if(!(T instanceof EventSet)){ +// // This collection should contain event sets, not transitions. +// throw new IllegalArgumentException("The eventSet was a Transition object not an EventSet object."); +// } +// EventSet es = (EventSet) T; +// +// newE.add(es.clone()); +// } + + +//#ifdef __LHPN_ADD_ACTION__ +//printf("At done & possible...\n"); +//#endif +//if(!done && possible) { +//eSet->insert(e); +//newE->push_back(*eSet); +//} + + if(!done && possible){ + eSet.add(e); + newE.add(eSet); + } + +//E.clear(); +//E = *newE; + + E = newE; + +//#ifdef __LHPN_ADD_ACTION__ +//printf("Event sets leaving:\n"); +//printEventSets(E,events,ineqL); +//#endif +//#ifdef __LHPN_TRACE__ +//printf("lhpnAddSetItem:end()\n"); +//#endif +//} + return E; + } + + @Override + public int getVarIndex(int lpnIndex, String name){ + return _lpnList[lpnIndex]. + getContinuousIndexMap().getValue(name); + } + + /** + * Adds a set item and explicitly sets a flag to remove the next set item + * upon firing. + * @param E + * The list of current event sets. + * @param e + * The event to add. + * @param s + * The current state. + * @param removeNext + * True if afer firing this event, the next event should be removed from the + * queue. + * @return + * The new event set. + */ +// public static LpnTranList addSetItem(LpnTranList E, Event e, State s, +// boolean removeNext){ +// +// return null; +// } + + /** + * Updates the continuous variables that are set by firing a transition. + * @param firedTran + * The transition that fired. + * @param s + * The current (local) state. + */ + public void updateContinuousAssignment(Transition firedTran, State s){ + + // Get the LPN. + LPN lpn = _lpnList[firedTran.getLpn().getLpnIndex()]; + + // Get the current values of the (local) state. + HashMap currentValues = + lpn.getAllVarsWithValuesAsString(s.getVariableVector()); + + // Get all the continuous variable assignments. + HashMap assignTrees = firedTran.getContAssignTrees(); + + for(String contVar : assignTrees.keySet()){ + + // Get the bounds to assign the continuous variables. + IntervalPair assignment = + assignTrees.get(contVar).evaluateExprBound(currentValues, this, null); + + // Make the assignment. + setContinuousBounds(contVar, lpn, assignment); + } + + } + + /** + * Updates the continuous variables according to the given values. + * @param newContValues + * The new values of the continuous variables. + */ +// public void updateContinuousAssignment(ArrayList> newAssignValues){ +// public void updateContinuousAssignment(ArrayList newAssignValues){ + public void updateContinuousAssignment(ContinuousRecordSet newAssignValues){ + /* + * In dealing with the rates and continuous variables, there are four cases to consider. These cases + * depend on whether the the old value of the 'current rate' is zero or non-zero and whether the + * new value of the 'current rate' is zero or non-zero. + * 0. old rate is zero, new rate is zero. + * Lookup the zero rate in the _rateZeroContinuous and add any new continuous assignments. + * 1. old rate is zero, new rate is non-zero. + * Remove the rate from the _rateZeroContinuous and add the zone. + * 2. old rate is non-zero, new rate is zero. + * Add the variable with its upper and lower bounds to _rateZeroContinuous. + * 3. old rate is non-zero, new rate is non-zero. + * Get the LPNContinuousPair from the _indexToTimerPair and change the value. + * + * Note: If an assignment is made to the variable, then it should be considered as a + * new variable. + */ + + + // The updating of the rate-zero continuous variables is taken care of + // by the copyRates. So just need to update the values in the zone. + // This amounts to copying over the values from the old zone for + // continuous variables that haven't changed and copying in + // values for the new vlues. + + +// final int OLD_ZERO = 0; // Case 0 in description. +// final int NEW_NON_ZERO = 1; // Case 1 in description. +// final int NEW_ZERO = 2; // Case 2 in description. +// final int OLD_NON_ZERO = 3; // Cade 3 in description. + + +// HashMap newNonZero = +// newAssignValues.get(NEW_NON_ZERO); +// HashMap oldNonZero = +// newAssignValues.get(OLD_NON_ZERO); + + +// for(Entry pair : newNonZero.entrySet()){ +// // Set the lower bound. +// setDbmEntryByPair(pair.getKey()._lcPair, +// LPNTransitionPair.ZERO_TIMER_PAIR, (-1)*pair.getValue().get_LowerBound()); +// +// // Set the upper bound. +// setDbmEntryByPair(pair.getKey().get_lcPair(), +// LPNTransitionPair.ZERO_TIMER_PAIR, pair.getValue().get_UpperBound()); +// +// // Set the rate. +// LPNTransitionPair ltpair = pair.getKey().get_lcPair(); +// +// int index = Arrays.binarySearch(_indexToTimerPair, ltpair); +// +// _matrix[dbmIndexToMatrixIndex(index)][0] = -1*pair.getKey().get_rateInterval().get_LowerBound(); +// _matrix[0][dbmIndexToMatrixIndex(index)] = pair.getKey().get_rateInterval().get_UpperBound(); +// } + + +// for(Entry pair : oldNonZero.entrySet()){ +// // Set the lower bound. +// setDbmEntryByPair(pair.getKey().get_lcPair(), +// LPNTransitionPair.ZERO_TIMER_PAIR, (-1)*pair.getValue().get_LowerBound()); +// +// // Set the upper bound. +// setDbmEntryByPair(LPNTransitionPair.ZERO_TIMER_PAIR, pair.getKey().get_lcPair(), +// pair.getValue().get_UpperBound()); +// +// int index = Arrays.binarySearch(_indexToTimerPair, pair.getKey().get_lcPair()); +// +// // Set the current rate. +// LPNTransitionPair ltPair = pair.getKey().get_lcPair(); +// setCurrentRate(ltPair, pair.getKey().get_lcPair().getCurrentRate()); +// +// // Set the upper and lower bounds for the rates. +// _matrix[dbmIndexToMatrixIndex(index)][0] = -1*pair.getKey().get_rateInterval().get_LowerBound(); +// _matrix[0][dbmIndexToMatrixIndex(index)] = pair.getKey().get_rateInterval().get_UpperBound(); +// } + + } + + /* (non-Javadoc) + * @see verification.timed_state_exploration.zone.Zone#getLexicon() + */ +// public HashMap getLexicon(){ +// if(_indexToTransition == null){ +// return null; +// } +// +// return new HashMap(_indexToTransition); +// } +// +// public void setLexicon(HashMap lexicon){ +// _indexToTransition = lexicon; +// } + + /** + * Gives an array that maps the index of a timer in the DBM to the timer's index. + * @return + * The array that maps the index of a timer in the DBM to the timer's index. + */ +// public int[] getIndexToTimer(){ +// return Arrays.copyOf(_indexToTimerPair, _indexToTimerPair.length); +// } + + /** + * Calculates a warping value needed to warp a Zone. When a zone is being warped the form + * r1*z2 - r1*z1 + r2*z1 becomes important in finding the new values of the zone. For example, + * + * @param z1 + * Upper bound or negative lower bound. + * @param z2 + * Relative value. + * @param r1 + * First ratio. + * @param r2 + * Second ratio. + * @return + * r1*z2 - r1*z1 + r2*z1 + */ + public static int warp(int z1, int z2, int r1, int r2){ + /* + * See "Verification of Analog/Mixed-Signal Circuits Using Labeled Hybrid Petri Nets" + * by S. Little, D. Walter, C. Myers, R. Thacker, S. Batchu, and T. Yoneda + * Section III.C for details on how this function is used and where it comes + * from. + */ + + return r1*z2 - r1*z1 + r2*z1; + } + + /** + * Warps this Zone with the aid of rate information from the previous Zone. + * + * @param oldZone + * The previous Zone. + * @return + * The warped Zone. + */ + //*public void dbmWarp(Zone oldZone){ + @Override + public void dbmWarp(Equivalence oldE){ + Zone oldZone = (Zone) oldE; + /* + * See "Verification of Analog/Mixed-Signal Circuits Using Labeled Hybrid Petri Nets" + * by S. Little, D. Walter, C. Myers, R. Thacker, S. Batchu, and T. Yoneda + * Section III.C for details on how this function is used and where it comes + * from. + */ + +// return null; + +// void lhpnDbmWarp(lhpnStateADT s,eventADT *events,int nevents) +// { +// #ifdef __LHPN_TRACE__ +// printf("lhpnDbmWarp:begin()\n"); +// #endif +// /* TODO: This appears to NOT work when INFIN is in the bounds? +// Should I have to worry about this case? */ +// for(int i=1;iz->dbmEnd;i++) { +// for(int j=i+1;jz->dbmEnd;j++) { +// double iVal = 0.0; +// double jVal = 0.0; +// double iWarp = 0; +// double jWarp = 0; +// double iXDot = 0; +// double jXDot = 0; +// + // According to atacs comments, this appears to NOT work when + // INFIN is in the bounds. + // This portion of the code handles the warping of the relative + // parts of the zone. + for(int i=1; i< dbmSize(); i++){ + for(int j=i+1; j%d\n",i,j); +// #endif +// if(s->z->curClocks[i].enabling == -2) { +// iVal = fabs((double)s->r->oldBound[s->z->curClocks[i].enabled-nevents].current / +// (double)s->r->bound[s->z->curClocks[i].enabled-nevents].current); +// iWarp = fabs((double)s->r->oldBound[s->z->curClocks[i].enabled-nevents].current); +// iXDot = fabs((double)s->r->bound[s->z->curClocks[i].enabled-nevents].current); +// } + + // Do some warping when dealing with the continuous variables. + if(_indexToTimerPair[i] instanceof LPNContinuousPair){ + // Calcualte the alpha value. + iVal = Math.floor(Math.abs( + (double) oldZone.getCurrentRate(_indexToTimerPair[i]) / + (double) this.getCurrentRate(_indexToTimerPair[i]))); + + // The old rate the zone was warped by. + iWarp = Math.floor(Math.abs( + (double) oldZone.getCurrentRate(_indexToTimerPair[i]))); + + // The current rate rate of this continuous variable. + iXDot = Math.floor(Math.abs( + (double) this.getCurrentRate(_indexToTimerPair[i]))); + + // I'm not going to do any warping when the previous rate + // is zero. This statement is a break to go to next i value + // and not the next j. + if(iWarp == 0){ + break; + } + } + +// else { +// iVal = 1.0; +// iWarp = 1.0; +// iXDot = 1.0; +// } +// + else{ + // The current variable is a timer, so the new rate and old rate + // are both 1. Hence we have + iVal = 1.0; + iWarp = 1.0; + iXDot = 1.0; + } + +// if(s->z->curClocks[j].enabling == -2) { +// jVal = fabs((double)s->r->oldBound[s->z->curClocks[j].enabled-nevents].current / +// (double)s->r->bound[s->z->curClocks[j].enabled-nevents].current); +// jWarp = fabs((double)s->r->oldBound[s->z->curClocks[j].enabled-nevents].current); +// jXDot = fabs((double)s->r->bound[s->z->curClocks[j].enabled-nevents].current); +// } + + // Do some warping of the second variable if it is a continuous variable. + if(_indexToTimerPair[j] instanceof LPNContinuousPair){ + // Calcualte the alpha value. + jVal = Math.floor(Math.abs( + (double) oldZone.getCurrentRate(_indexToTimerPair[j]) / + (double) this.getCurrentRate(_indexToTimerPair[j]))); + + // The old rate the zone was warped by. + jWarp = Math.floor(Math.abs( + (double) oldZone.getCurrentRate(_indexToTimerPair[j]))); + + // The current rate of this continuous variable. + jXDot = Math.floor(Math.abs( + (double) this.getCurrentRate(_indexToTimerPair[j]))); + + // I'm not going to do any warping when the previous rate is + // zero. + if(jWarp == 0){ + continue; + } + } + +// else { +// jVal = 1.0; +// jWarp = 1.0; +// jXDot = 1.0; +// } +// + else{ + // The current variable is a timer, so the new rate and old rate + // are both 1. Hence we have + jVal = 1.0; + jWarp = 1.0; + jXDot = 1.0; + } + +// #ifdef __LHPN_DEBUG_WARP__ +// printf("iVal: %f, jVal: %f, iWarp: %f, jWarp: %f, iXDot: %f, jXDot: %f\n",iVal,jVal,iWarp,jWarp,iXDot,jXDot); +// /* printf("calc1- jWarp:%d * s->z->matrix[i][j]:%d / jXDot:%d + (-1 * jWarp:%d * s->z->matrix[i][0]:%d) / jXDot:%d + (iWarp:%d * s->z->matrix[i][0]:%d) / iXDot:%d = %d 1:%d 2:%d 3:%d -- %d\n", jWarp,s->z->matrix[i][j],jXDot,jWarp,s->z->matrix[i][0],jXDot,iWarp,s->z->matrix[i][0],iXDot,(chkDiv((jWarp * s->z->matrix[i][j]),jXDot,'C') + chkDiv((-1 * jWarp * s->z->matrix[i][0]),jXDot,'C') + chkDiv((iWarp * s->z->matrix[i][0]),iXDot,'C')),chkDiv((jWarp * s->z->matrix[i][j]),jXDot,'C'),chkDiv((-1 * jWarp * s->z->matrix[i][0]),jXDot,'C'),chkDiv((iWarp * s->z->matrix[i][0]),iXDot,'C'),(int)ceil(((jWarp * s->z->matrix[i][j])/jXDot) +((-1 * jWarp * s->z->matrix[i][0])/jXDot) + ((iWarp * s->z->matrix[i][0])/iXDot))); */ +// /* printf("calc2-jWarp:%f * s->z->matrix[j][i]):%d/jXDot:%f) + ((-1 * jWarp:%f * s->z->matrix[0][i]:%d)/jXDot:%f) + ((iWarp:%f * s->z->matrix[0][i]):%d,iXDot:%f)) = %d 1:%f 2:%f 3:%f\n",jWarp,s->z->matrix[j][i],jXDot,jWarp,s->z->matrix[0][i],jXDot,iWarp,s->z->matrix[0][i],iXDot,(int) ceil(((jWarp * s->z->matrix[j][i])/jXDot) + ((-1 * jWarp * s->z->matrix[0][i])/jXDot) + ((iWarp * s->z->matrix[0][i]),iXDot)),((jWarp * (double)s->z->matrix[j][i])/jXDot),((-1 * jWarp * (double)s->z->matrix[0][i])/jXDot),(iWarp * (double)s->z->matrix[0][i])/iXDot); */ +// #endif +// +// if(iVal > jVal) { +// /* s->z->matrix[i][j] = */ +// /* chkDiv((jWarp * s->z->matrix[i][j]),jXDot,'C') + */ +// /* chkDiv((-1 * jWarp * s->z->matrix[i][0]),jXDot,'C') + */ +// /* chkDiv((iWarp * s->z->matrix[i][0]),iXDot,'C'); */ +// /* s->z->matrix[j][i] = */ +// /* chkDiv((jWarp * s->z->matrix[j][i]),jXDot,'C') + */ +// /* chkDiv((-1 * jWarp * s->z->matrix[0][i]),jXDot,'C') + */ +// /* chkDiv((iWarp * s->z->matrix[0][i]),iXDot,'C'); */ +// s->z->matrix[i][j] = (int) +// ceil(((jWarp * s->z->matrix[i][j])/jXDot) + +// ((-1 * jWarp * s->z->matrix[i][0])/jXDot) + +// ((iWarp * s->z->matrix[i][0])/iXDot)); +// s->z->matrix[j][i] = (int) +// ceil(((jWarp * s->z->matrix[j][i])/jXDot) + +// ((-1 * jWarp * s->z->matrix[0][i])/jXDot) + +// ((iWarp * s->z->matrix[0][i])/iXDot)); +// } + + // The zone is warped differently depending on which of rate is + // larger. See Scott Little's Thesis for more details. + //if(iVal > jVal){ + if(iWarp*jXDot > jWarp*iXDot ){ + setDbmEntry(j, i, (int) + Math.ceil(((jWarp*getDbmEntry(j, i))/jXDot) + + ((-1*jWarp*getDbmEntry(0, i)/jXDot)) + + ((iWarp*getDbmEntry(0, i)/iXDot)))); + + setDbmEntry(i, j, (int) + Math.ceil(((jWarp*getDbmEntry(i, j))/jXDot) + + ((-1*jWarp*getDbmEntry(i, 0)/jXDot)) + + ((iWarp*getDbmEntry(i, 0)/iXDot)))); + } + +// else { +// /* s->z->matrix[j][i] = */ +// /* chkDiv((iWarp * s->z->matrix[j][i]),iXDot,'C') + */ +// /* chkDiv((-1 * iWarp * s->z->matrix[j][0]),iXDot,'C') + */ +// /* chkDiv((jWarp * s->z->matrix[j][0]),jXDot,'C'); */ +// /* s->z->matrix[i][j] = */ +// /* chkDiv((iWarp * s->z->matrix[i][j]),iXDot,'C') + */ +// /* chkDiv((-1 * iWarp * s->z->matrix[0][j]),iXDot,'C') + */ +// /* chkDiv((jWarp * s->z->matrix[0][j]),jXDot,'C'); */ +// s->z->matrix[j][i] = (int) +// ceil(((iWarp * s->z->matrix[j][i])/iXDot) + +// ((-1 * iWarp * s->z->matrix[j][0])/iXDot) + +// ((jWarp * s->z->matrix[j][0])/jXDot)); +// s->z->matrix[i][j] = (int) +// ceil(((iWarp * s->z->matrix[i][j])/iXDot) + +// ((-1 * iWarp * s->z->matrix[0][j])/iXDot) + +// ((jWarp * s->z->matrix[0][j])/jXDot)); +// } + + else{ + setDbmEntry(i, j, (int) + Math.ceil(((iWarp*getDbmEntry(i, j))/iXDot) + + ((-1*iWarp*getDbmEntry(0, j)/iXDot)) + + ((jWarp*getDbmEntry(0, j)/jXDot)))); + + setDbmEntry(j, i, (int) + Math.ceil(((iWarp*getDbmEntry(j, i))/iXDot) + + ((-1*iWarp*getDbmEntry(j, 0)/iXDot)) + + ((jWarp*getDbmEntry(j, 0)/jXDot)))); + } +// } +// } +// + } + } +// #ifdef __LHPN_DEBUG_WARP__ +// printf("After fixing up initial warp conditions.\n"); +// printZ(s->z,events,nevents,s->r); +// #endif +// +// for(int i=1;iz->dbmEnd;i++) { +// if(s->z->curClocks[i].enabling == -2) { + + // Handle the warping of the bounds. + for(int i=1; ir->oldBound[s->z->curClocks[i].enabled-nevents].current,s->r->bound[s->z->curClocks[i].enabled-nevents].current,s->z->matrix[0][i],s->z->matrix[i][0]); +// #endif +// if(abs(s->z->matrix[0][i]) != INFIN) { +// s->z->matrix[0][i] = +// chkDiv((abs(s->r->oldBound[s->z->curClocks[i].enabled-nevents].current) +// * s->z->matrix[0][i]), +// abs(s->r->bound[s->z->curClocks[i].enabled-nevents].current) +// ,'C'); +// } + + if(Math.abs(getDbmEntry(i, 0)) != INFINITY ){ + + if(oldZone.getCurrentRate(_indexToTimerPair[i]) == 0){ + // If the older rate was zero, then we just need to + // divide by the new rate. + setDbmEntry(i, 0, ContinuousUtilities.chkDiv( + getDbmEntry(i,0), + Math.abs(getCurrentRate(_indexToTimerPair[i])), + true)); + } + else{ + // Undo the old warping and introduce the new warping. + // If the bound is infinite, then division does nothing. + setDbmEntry(i, 0, ContinuousUtilities.chkDiv( + Math.abs(oldZone.getCurrentRate(_indexToTimerPair[i])) + * getDbmEntry(i, 0), + Math.abs(getCurrentRate(_indexToTimerPair[i])), + true)); + } + } + +// if(abs(s->z->matrix[i][0]) != INFIN) { +// s->z->matrix[i][0] = +// chkDiv((abs(s->r->oldBound[s->z->curClocks[i].enabled-nevents].current) +// * s->z->matrix[i][0]), +// abs(s->r->bound[s->z->curClocks[i].enabled-nevents].current) +// ,'C'); +// } + + if(Math.abs(getDbmEntry(0, i)) != INFINITY){ + + if(oldZone.getCurrentRate(_indexToTimerPair[i]) == 0){ + setDbmEntry(0, i, ContinuousUtilities.chkDiv( + getDbmEntry(0,i), + Math.abs(getCurrentRate(_indexToTimerPair[i])), + true)); + } + else{ + // Undo the old warping and introduce the new warping. + // If the bound is inifite, then division does nothing. + setDbmEntry(0, i, ContinuousUtilities.chkDiv( + Math.abs(oldZone.getCurrentRate(_indexToTimerPair[i])) + * getDbmEntry(0, i), + Math.abs(getCurrentRate(_indexToTimerPair[i])), + true)); + } + } +// } +// } +// + } + } + + +// #ifdef __LHPN_DEBUG_WARP__ +// printf("After fixing up places.\n"); +// printZ(s->z,events,nevents,s->r); +// #endif +// +// for(int i=1;iz->dbmEnd;i++) { +// if(s->z->curClocks[i].enabling == -2) { + + for(int i=1; ir->oldBound[s->z->curClocks[i].enabled-nevents].current); +// #endif +// if(((float)s->r->oldBound[s->z->curClocks[i].enabled-nevents].current / +// (float)s->r->bound[s->z->curClocks[i].enabled-nevents].current) < 0.0) { +// /* swap */ +// int temp = s->z->matrix[0][i]; +// s->z->matrix[0][i] = s->z->matrix[i][0]; +// s->z->matrix[i][0] = temp; +// +// for(int j=1;jz->dbmEnd;j++) { +// /* TBD: If i & j are both changing direction do we need to +// remove the warp info? */ +// if(i != j) { +// s->z->matrix[j][i] = INFIN; +// s->z->matrix[i][j] = INFIN; +// } +// } +// } +// } +// } +// + // Handle the case when the warping takes us into negative space. + if((double) oldZone.getCurrentRate(_indexToTimerPair[i])/ + (double) this.getCurrentRate(_indexToTimerPair[i]) < 0.0){ + /* We are warping into the negative space, so swap the upper and + * lower bounds. + */ + int temp = getDbmEntry(i, 0); + setDbmEntry(i,0, getDbmEntry(0, i)); + setDbmEntry(0, i, temp); + + + // Set the relationships to Infinity since nothing else is known. + for(int j=1; jz,events,nevents,s->r); +// #endif +// +// for(int i=1;iz->dbmEnd;i++) { +// if(s->z->curClocks[i].enabling == -2) { + +// for(int i=1; ir->bound[s->z->curClocks[i].enabled-nevents].current; +// int newLwarp = s->r->bound[s->z->curClocks[i].enabled-nevents].lower; +// int newUwarp = s->r->bound[s->z->curClocks[i].enabled-nevents].upper; +// s->r->oldBound[s->z->curClocks[i].enabled-nevents].current = newCwarp; +// s->r->oldBound[s->z->curClocks[i].enabled-nevents].lower = newLwarp; +// s->r->oldBound[s->z->curClocks[i].enabled-nevents].upper = newUwarp; +// +// #ifdef __LHPN_DEBUG_WARP__ +// printf("New warp for %d: %d\n",i,s->r->oldBound[s->z->curClocks[i].enabled-nevents].current); +// #endif +// } +// } +// + /* Do the nature of how I store things, I do not think I need to do + * this portion. + */ + + +// } +// } + +// #ifdef __LHPN_DEBUG_WARP__ +// printf("Before recanon.\n"); +// printZ(s->z,events,nevents,s->r); +// #endif +// recanonZ(s->z); +// #ifdef __LHPN_DEBUG_WARP__ +// printf("After recanon.\n"); +// printZ(s->z,events,nevents,s->r); +// #endif +// } + } + + + //----------------------Inner Classes----------------------------------------------- + /** + * The DiagonalNonZeroException extends the java.lang.RuntimerExpcetion. + * The intention is for this exception to be thrown is a Zone has a non zero + * entry appear on the diagonal. + * + * @author Andrew N. Fisher + * + */ + public class DiagonalNonZeroException extends java.lang.RuntimeException + { + + /** + * Generated serialVersionUID. + */ + private static final long serialVersionUID = -3857736741611605411L; + + /** + * Creates a DiagonalNonZeroException. + * @param Message + * The message to be displayed when the exception is thrown. + */ + public DiagonalNonZeroException(String Message) + { + super(Message); + } + } + + /** + * This exception is thrown when trying to merge two zones whose corresponding timers + * do not agree. + * @author Andrew N. Fisher + * + */ +// public class IncompatibleZoneException extends java.lang.RuntimeException +// { +// +// // TODO : Check if this class can be removed. +// +// /** +// * Generated serialVersionUID +// */ +// private static final long serialVersionUID = -2453680267411313227L; +// +// +// public IncompatibleZoneException(String Message) +// { +// super(Message); +// } +// } + + + /** + * Clears out the lexicon. + */ +// public static void clearLexicon(){ +// _indexToTransition = null; +// } + + public static IntervalPair parseRate(String rate){ + + String rateNoSpaces = rate.trim(); + + // First check if the string is a single number. +// Integer i = Integer.parseInt(rate); +// if(i != null){ +// // The string is a number, so set the upper and lower bounds equal. +// return new IntervalPair(i,i); +// } + + // First check for a comma (representing an interval input). + int commaIndex = rateNoSpaces.indexOf(","); + + if(commaIndex < 0){ + // Assume that the string is a constant. A NumberFormatException + // will be thrown otherwise. + int i = Integer.parseInt(rate); + return new IntervalPair(i,i); + } + + String lowerString = rateNoSpaces.substring(1, commaIndex).trim(); + String upperString = rateNoSpaces.substring(commaIndex+1, + rateNoSpaces.length()-1).trim(); + + return new IntervalPair(Integer.parseInt(lowerString), + Integer.parseInt(upperString)); + } + + /** + * Get the list of LhpnFile objects that this Zone depends on. + * @return + * The lits of LhpnFile objects that this Zone depends on. + */ + @Override + public LPN[] get_lpnList(){ + return _lpnList; + } + + /** + * Performs a division of two integers and either takes the ceiling or the floor. Note : + * The integers are converted to doubles for the division so the choice of ceiling or floor is + * meaningful. + * @param top + * The numerator. + * @param bottom + * The denominator. + * @param ceil + * True indicates return the ceiling and false indicates return the floor. + * @return + * Returns the ceiling of top/bottom if ceil is true and the floor of top/bottom otherwise. + */ +// public int chkDiv(int top, int bottom, Boolean ceil){ +// /* +// * This method was taken from atacs/src/hpnrsg.c +// */ +// int res = 0; +// if(top == INFINITY || +// top == INFINITY * -1) { +// if(bottom < 0) { +// return top * -1; +// } +// return top; +// } +// if(bottom == INFINITY) { +// return 0; +// } +// if(bottom == 0) { +// System.out.println("Warning: Divided by zero."); +// bottom = 1; +// } +// +// double Dres,Dtop,Dbottom; +// Dtop = top; +// Dbottom = bottom; +// Dres = Dtop/Dbottom; +// if(ceil) { +// res = (int)Math.ceil(Dres); +// } +// else if(!ceil) { +// res = (int)Math.floor(Dres); +// } +// return res; +// } + + /** + * Returns the current rate of the variable. + * @param contVar + * The LPNTransitionPair referring to a continuous variable. + * @return + * The current rate of the continuous variable refenced by the LPNTransitionPair. + * @throws IllegalArgumentException + * If the LPNTransitionPair is not an instance of an LPNContinuousPair. + */ + @Override + public int getCurrentRate(LPNTransitionPair contVar){ + + if(!(contVar instanceof LPNContinuousPair)){ + // The LPNTransitionsPair does not refer to a continuous variable, so yell. + throw new IllegalArgumentException("Zone.getCurrentRate was called" + + " on an LPNTransitionPair that was not an LPNContinuousPair."); + } + + LPNContinuousPair cV = (LPNContinuousPair) contVar; + + // Search for the pair in the zone. + int index = Arrays.binarySearch(_indexToTimerPair, cV); + if(index >0){ + // The continuous variable was found amongst the non zero rate continuous variables. + // Grab that indexing object instead since it has the rate. + cV = (LPNContinuousPair) _indexToTimerPair[index]; + return cV.getCurrentRate(); + } + // Since the variable was not found in the non-zero rate continuous + // variables, assume the rate is zero. + return 0; + } + + /** + * Sets the current rate for a continuous variable. It sets the rate regardless of + * whether the variable is in the rate zero portion of the Zone or not. But it + * does not move variables in and out of the zone. + * @param contVar + * The index of the variable whose rate is going to be set. + * @param currentRate + * The value of the rate. + */ + @Override + public void setCurrentRate(LPNTransitionPair contVar, int currentRate){ + + if(!(contVar instanceof LPNContinuousPair)){ + // The LPNTransitionsPair does not refer to a continuous variable, so yell. + throw new IllegalArgumentException("Zone.getCurrentRate was called" + + " on an LPNTransitionPair that was not an LPNContinuousPair."); + } + + + LPNContinuousPair cV = (LPNContinuousPair) contVar; + + // Check for the current variable in the rate zero variables. + + VariableRangePair variableRange = _rateZeroContinuous. + getValue(new LPNContAndRate(cV, new IntervalPair(0,0))); + + if(variableRange != null){ + LPNContinuousPair lcPair = _rateZeroContinuous. + getKey(variableRange).get_lcPair(); + lcPair.setCurrentRate(currentRate); + return; + } + + // Check for the current variable in the Zone variables. + int index = Arrays.binarySearch(_indexToTimerPair, contVar); + + if(index >= 0){ + // The variable was found, set the rate. + LPNContinuousPair lcPair = (LPNContinuousPair) _indexToTimerPair[index]; + lcPair.setCurrentRate(currentRate); + } + } + + /** + * Adds a transition to a zone. + * @param newTransitions + * The newly enabled transitions. + * @return + * The result of adding the transition. + */ + @Override + public Zone addTransition(HashSet newTransitions, State[] localStates){ + /* + * The zone will remain the same for all the continuous variables. + * The only thing that will change is a new transition will be added into the transitions. + */ + + // Create a Zone to alter. + Zone newZone = new Zone(); + + // Create a copy of the LPN list. + newZone._lpnList = Arrays.copyOf(this._lpnList, this._lpnList.length); + + // Copy the rate zero continuous variables. + newZone._rateZeroContinuous = this._rateZeroContinuous.clone(); + + // Create a copy of the current indexing pairs. + //newZone._indexToTimerPair = Arrays.copyOf(_indexToTimerPair, _indexToTimerPair.length); + newZone._indexToTimerPair = new LPNTransitionPair[_indexToTimerPair.length + newTransitions.size()]; + for(int i=0; i<_indexToTimerPair.length; i++){ + newZone._indexToTimerPair[i] = _indexToTimerPair[i]; + } + + + // Add the new transitions to the _indexToTimerPair list. +// for(int i=_indexToTimerPair.length; i oldTransitionSet = new HashSet(); + for(LPNTransitionPair ltPair : _indexToTimerPair){ + oldTransitionSet.add(ltPair); + } + + // Copy in the new transitions. + newZone.copyTransitions(this, newTransitions, oldTransitionSet, localStates); + +// newZone.advance(localStates); +// +// newZone.recononicalize(); + + return newZone; + } + + /** + * This method creates a zone identical to the current zone except all the current rates are turned to 1. + * This is to provide a previous zone to the initial zone for warping. + * @return + * A zone identical to this zone with all rates set to 1. + */ + private Zone beforeInitialZone(){ + Zone z = this.clone(); + +// for(int i=1; _indexToTimerPair[i] instanceof LPNContinuousPair; i++){ + for(int i=1; i oldTransitionSet = new HashSet(); + for(LPNTransitionPair ltPair : _indexToTimerPair){ + oldTransitionSet.add(ltPair); + } + + // Copy in the new transitions. + newZone.copyTransitions(this, new HashSet(), + oldTransitionSet, null); + + // Get the index for the variable. + int index = Arrays.binarySearch(newZone._indexToTimerPair, ltContPair); + + + + // Copy in the upper and lower bound of the old rate zero variable. +// newZone.setLowerBoundByLPNTransitionPair(ltContPair, +// rangeOfRates.get_LowerBound()); +// newZone.setUpperBoundByLPNTransitionPair(ltContPair, +// rangeOfRates.get_UpperBound()); + + // Copy in the range of rates. + newZone.setLowerBoundbydbmIndex(index, rangeOfRates.get_LowerBound()); + newZone.setUpperBoundbydbmIndex(index, rangeOfRates.get_UpperBound()); + + if(ltContPair.getCurrentRate()>0){ + + // Set the upper and lower bounds. + newZone.setDbmEntry(0, index, + ContinuousUtilities.chkDiv(values.get_UpperBound(), + ltContPair.getCurrentRate(), true)); + newZone.setDbmEntry(index, 0, + ContinuousUtilities.chkDiv(-1*values.get_LowerBound(), + ltContPair.getCurrentRate(), true)); + } + else{ + // Set the upper and lower bounds. Since the rate is zero + // We swap the real upper and lower bounds. + newZone.setDbmEntry(0, index, + ContinuousUtilities.chkDiv(values.get_LowerBound(), + ltContPair.getCurrentRate(), true)); + newZone.setDbmEntry(index, 0, + ContinuousUtilities.chkDiv(-1*values.get_UpperBound(), + ltContPair.getCurrentRate(), true)); + } + + // Set the DBM to having no relating information for how this + // variables relates to the other variables. + for(int i=1; i variableIndecies = lpn.getContinuousIndexMap(); +// int contIndex = variableIndecies.get(contVar); +// +// // Package up the information into a the index. Note the current rate doesn't matter. +// LPNContinuousPair index = new LPNContinuousPair(lpn.getLpnIndex(), contIndex, 0); +// +// // Get the current rate. +// int currentRate = getCurrentRate(index); +// +// // Get the current value of the inequality. This requires looking into the current state. +//// int currentValue = localStates[lpn.getLpnIndex()].getCurrentValue(contIndex); +// int currentValue = localState.getCurrentValue(contIndex); +// +// // Get the Zone index of the variable. +// int zoneIndex = Arrays.binarySearch(_indexToTimerPair, index); +// +//// bool lhpnPredCanChange(ineqADT ineq,lhpnZoneADT z,lhpnRateADT r, +//// lhpnMarkingADT m,eventADT *events,int nevents, +//// lhpnStateADT s) +////{ +////ineq_update(ineq,s,nevents); +//// +//// +////#ifdef __LHPN_TRACE__ +////printf("lhpnPredCanChange:begin()\n"); +////#endif +////#ifdef __LHPN_PRED_DEBUG__ +////printf("lhpnPredCanChange Examining: "); +////printI(ineq,events); +////printf("signal = %c, %d",s->m->state[ineq->signal],r->bound[ineq->place-nevents].current); +////printf("\n"); +////if (r->bound[ineq->place-nevents].current != 0) +////printf("divRes: %d\n",chkDiv(ineq->constant, +//// r->bound[ineq->place-nevents].current,'F')); +////#endif +/////* > or >= */ +////if(ineq->type == 0 || ineq->type == 1) { +// +// // > or >= +// if(ineq.get_op().contains(">")){ +// +////int zoneP = getIndexZ(z,-2,ineq->place); +////if(zoneP == -1) { +////warn("An inequality produced a place not in the zone."); +////return false; +////} +// +////if(r->bound[ineq->place-nevents].current < 0 && +////m->state[ineq->signal] == '1') { +// +// // First check cases when the rate is negative. +// if(currentRate < 0 && currentValue != 0){ +// +////if((-1)*z->matrix[zoneP][0] <= +//// (-1)*chkDiv(ineq->constant,r->bound[ineq->place-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("predCanChange:1\n"); +//// printf("rate: %d state: %c\n",r->bound[ineq->place-nevents].current, +//// m->state[ineq->signal]); +////#endif +//// return true; +// +// if((-1) * getDbmEntry(0, zoneIndex) <= +// (-1)*chkDiv(ineq.getConstant(), currentRate, false)){ +// return true; +// } +// +////} else { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("predCannotChange:1\n"); +//// printf("rate: %d state: %c\n",r->bound[ineq->place-nevents].current, +//// m->state[ineq->signal]); +////#endif +//// return false; +////} +////} +// else{ +// return false; +// } +// } +////else if(r->bound[ineq->place-nevents].current > 0 && +//// m->state[ineq->signal] == '0') { +// +// else if(currentRate > 0 && currentValue == 0){ +// +// +////if(z->matrix[zoneP][0] >= +//// chkDiv(ineq->constant,r->bound[ineq->place-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("predCanChange:2\n"); +//// printf("rate: %d state: %c\n",r->bound[ineq->place-nevents].current, +//// m->state[ineq->signal]); +////#endif +//// return true; +// +// +// if(getDbmEntry(0, zoneIndex) <= +// chkDiv(ineq.getConstant(), currentRate, false)){ +// return true; +// } +// +////} else { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("predCannotChange:2\n"); +//// printf("rate: %d state: %c\n",r->bound[ineq->place-nevents].current, +//// m->state[ineq->signal]); +////#endif +////return false; +// +// else{ +// return false; +// } +// +////} +////} +// +// } +////else { +////#ifdef __LHPN_PRED_DEBUG__ +////printf("predCannotChange:3\n"); +////printf("rate: %d state: %c\n",r->bound[ineq->place-nevents].current, +//// m->state[ineq->signal]); +////#endif +////return false; +////} +////} +// } +/////* < or <= */ +////else if(ineq->type == 2 || ineq->type == 3) { +// +// else if(ineq.get_op().contains("<")){ +// +////int zoneP = getIndexZ(z,-2,ineq->place); +////if(zoneP == -1) { +////warn("An inequality produced a place not in the zone."); +////return false; +////} +////if(r->bound[ineq->place-nevents].current < 0 && +////m->state[ineq->signal] == '0') { +// +// if(currentRate < 0 && currentValue == 0){ +// +////if((-1)*z->matrix[zoneP][0] <= +//// (-1)*chkDiv(ineq->constant,r->bound[ineq->place-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("predCanChange:4\n"); +//// printf("rate: %d state: %c\n",r->bound[ineq->place-nevents].current, +//// m->state[ineq->signal]); +////#endif +//// return true; +// +// if((-1) * getDbmEntry(0, zoneIndex) <= +// (-1)*chkDiv(ineq.getConstant(), currentRate, false)){ +// return true; +// } +// +// +////} else { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("predCannotChange:4\n"); +//// printf("rate: %d state: %c\n",r->bound[ineq->place-nevents].current, +//// m->state[ineq->signal]); +////#endif +//// return false; +// +// +// else{ +// return false; +// } +////} +////} +// } +////else if(r->bound[ineq->place-nevents].current > 0 && +//// m->state[ineq->signal] == '1') { +// +// else if (currentRate > 0 && +// currentValue != 0){ +// +// +////if(z->matrix[zoneP][0] >= +//// chkDiv(ineq->constant,r->bound[ineq->place-nevents].current,'F')) { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("predCanChange:5\n"); +//// printf("rate: %d state: %c\n",r->bound[ineq->place-nevents].current, +//// m->state[ineq->signal]); +////#endif +//// return true; +// +// +// if(getDbmEntry(0, zoneIndex) >= +// chkDiv(ineq.getConstant(), currentRate, false)){ +// return true; +// } +// +////} else { +////#ifdef __LHPN_PRED_DEBUG__ +//// printf("predCannotChange:5\n"); +//// printf("rate: %d state: %c\n",r->bound[ineq->place-nevents].current, +//// m->state[ineq->signal]); +////#endif +//// return false; +// +// +// else { +// return false; +// } +////} +////} +// } +////else { +////#ifdef __LHPN_PRED_DEBUG__ +////printf("predCanChange:6\n"); +////printf("rate: %d state: %c\n",r->bound[ineq->place-nevents].current, +//// m->state[ineq->signal]); +////#endif +////return false; +////} +// +// else { +// return false; +// } +// +////} +// } +////#ifdef __LHPN_PRED_DEBUG__ +////printf("predCanChange:7\n"); +////printf("rate: %d state: %c\n",r->bound[ineq->place-nevents].current, +//// m->state[ineq->signal]); +////#endif +////return false; +////} +// return false; +// } +}